OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "test/unittests/test-utils.h" | 5 #include "test/unittests/test-utils.h" |
6 | 6 |
7 #include "src/objects-inl.h" | 7 #include "src/objects-inl.h" |
8 #include "src/wasm/decoder.h" | 8 #include "src/wasm/decoder.h" |
9 #include "src/wasm/wasm-macro-gen.h" | 9 #include "src/wasm/wasm-macro-gen.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 namespace wasm { | 13 namespace wasm { |
14 | 14 |
15 class DecoderTest : public TestWithZone { | 15 class DecoderTest : public TestWithZone { |
16 public: | 16 public: |
17 DecoderTest() : decoder(nullptr, nullptr) {} | 17 DecoderTest() : decoder(nullptr, nullptr) {} |
18 | 18 |
19 Decoder decoder; | 19 Decoder decoder; |
20 }; | 20 }; |
21 | 21 |
22 #define CHECK_UINT32V_INLINE(expected, expected_length, ...) \ | 22 #define CHECK_UINT32V_INLINE(expected, expected_length, ...) \ |
23 do { \ | 23 do { \ |
24 const byte data[] = {__VA_ARGS__}; \ | 24 const byte data[] = {__VA_ARGS__}; \ |
25 decoder.Reset(data, data + sizeof(data)); \ | 25 decoder.Reset(data, data + sizeof(data)); \ |
26 int length; \ | 26 unsigned length; \ |
27 EXPECT_EQ(expected, \ | 27 EXPECT_EQ(expected, \ |
28 decoder.checked_read_u32v(decoder.start(), 0, &length)); \ | 28 decoder.checked_read_u32v(decoder.start(), 0, &length)); \ |
29 EXPECT_EQ(expected_length, length); \ | 29 EXPECT_EQ(expected_length, length); \ |
30 } while (false) | 30 } while (false) |
31 | 31 |
32 #define CHECK_INT32V_INLINE(expected, expected_length, ...) \ | 32 #define CHECK_INT32V_INLINE(expected, expected_length, ...) \ |
33 do { \ | 33 do { \ |
34 const byte data[] = {__VA_ARGS__}; \ | 34 const byte data[] = {__VA_ARGS__}; \ |
35 decoder.Reset(data, data + sizeof(data)); \ | 35 decoder.Reset(data, data + sizeof(data)); \ |
36 int length; \ | 36 unsigned length; \ |
37 EXPECT_EQ(expected, \ | 37 EXPECT_EQ(expected, \ |
38 decoder.checked_read_i32v(decoder.start(), 0, &length)); \ | 38 decoder.checked_read_i32v(decoder.start(), 0, &length)); \ |
39 EXPECT_EQ(expected_length, length); \ | 39 EXPECT_EQ(expected_length, length); \ |
40 } while (false) | 40 } while (false) |
41 | 41 |
42 #define CHECK_UINT64V_INLINE(expected, expected_length, ...) \ | 42 #define CHECK_UINT64V_INLINE(expected, expected_length, ...) \ |
43 do { \ | 43 do { \ |
44 const byte data[] = {__VA_ARGS__}; \ | 44 const byte data[] = {__VA_ARGS__}; \ |
45 decoder.Reset(data, data + sizeof(data)); \ | 45 decoder.Reset(data, data + sizeof(data)); \ |
46 int length; \ | 46 unsigned length; \ |
47 EXPECT_EQ(expected, \ | 47 EXPECT_EQ(expected, \ |
48 decoder.checked_read_u64v(decoder.start(), 0, &length)); \ | 48 decoder.checked_read_u64v(decoder.start(), 0, &length)); \ |
49 EXPECT_EQ(expected_length, length); \ | 49 EXPECT_EQ(expected_length, length); \ |
50 } while (false) | 50 } while (false) |
51 | 51 |
52 #define CHECK_INT64V_INLINE(expected, expected_length, ...) \ | 52 #define CHECK_INT64V_INLINE(expected, expected_length, ...) \ |
53 do { \ | 53 do { \ |
54 const byte data[] = {__VA_ARGS__}; \ | 54 const byte data[] = {__VA_ARGS__}; \ |
55 decoder.Reset(data, data + sizeof(data)); \ | 55 decoder.Reset(data, data + sizeof(data)); \ |
56 int length; \ | 56 unsigned length; \ |
57 EXPECT_EQ(expected, \ | 57 EXPECT_EQ(expected, \ |
58 decoder.checked_read_i64v(decoder.start(), 0, &length)); \ | 58 decoder.checked_read_i64v(decoder.start(), 0, &length)); \ |
59 EXPECT_EQ(expected_length, length); \ | 59 EXPECT_EQ(expected_length, length); \ |
60 } while (false) | 60 } while (false) |
61 | 61 |
62 TEST_F(DecoderTest, ReadU32v_OneByte) { | 62 TEST_F(DecoderTest, ReadU32v_OneByte) { |
63 CHECK_UINT32V_INLINE(0, 1, 0); | 63 CHECK_UINT32V_INLINE(0, 1, 0); |
64 CHECK_UINT32V_INLINE(5, 1, 5); | 64 CHECK_UINT32V_INLINE(5, 1, 5); |
65 CHECK_UINT32V_INLINE(7, 1, 7); | 65 CHECK_UINT32V_INLINE(7, 1, 7); |
66 CHECK_UINT32V_INLINE(9, 1, 9); | 66 CHECK_UINT32V_INLINE(9, 1, 9); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 } | 359 } |
360 | 360 |
361 const int32_t max = kMaxInt; | 361 const int32_t max = kMaxInt; |
362 for (int i = max; i > max - 10; i--) { | 362 for (int i = max; i > max - 10; i--) { |
363 CHECK_INT32V_INLINE(i, 5, U32V_5(i)); | 363 CHECK_INT32V_INLINE(i, 5, U32V_5(i)); |
364 } | 364 } |
365 } | 365 } |
366 | 366 |
367 TEST_F(DecoderTest, ReadU32v_off_end1) { | 367 TEST_F(DecoderTest, ReadU32v_off_end1) { |
368 static const byte data[] = {U32V_1(11)}; | 368 static const byte data[] = {U32V_1(11)}; |
369 int length = 0; | 369 unsigned length = 0; |
370 decoder.Reset(data, data); | 370 decoder.Reset(data, data); |
371 decoder.checked_read_u32v(decoder.start(), 0, &length); | 371 decoder.checked_read_u32v(decoder.start(), 0, &length); |
372 EXPECT_EQ(0, length); | 372 EXPECT_EQ(0, length); |
373 EXPECT_FALSE(decoder.ok()); | 373 EXPECT_FALSE(decoder.ok()); |
374 } | 374 } |
375 | 375 |
376 TEST_F(DecoderTest, ReadU32v_off_end2) { | 376 TEST_F(DecoderTest, ReadU32v_off_end2) { |
377 static const byte data[] = {U32V_2(1111)}; | 377 static const byte data[] = {U32V_2(1111)}; |
378 for (size_t i = 0; i < sizeof(data); i++) { | 378 for (size_t i = 0; i < sizeof(data); i++) { |
379 int length = 0; | 379 unsigned length = 0; |
380 decoder.Reset(data, data + i); | 380 decoder.Reset(data, data + i); |
381 decoder.checked_read_u32v(decoder.start(), 0, &length); | 381 decoder.checked_read_u32v(decoder.start(), 0, &length); |
382 EXPECT_EQ(i, length); | 382 EXPECT_EQ(i, length); |
383 EXPECT_FALSE(decoder.ok()); | 383 EXPECT_FALSE(decoder.ok()); |
384 } | 384 } |
385 } | 385 } |
386 | 386 |
387 TEST_F(DecoderTest, ReadU32v_off_end3) { | 387 TEST_F(DecoderTest, ReadU32v_off_end3) { |
388 static const byte data[] = {U32V_3(111111)}; | 388 static const byte data[] = {U32V_3(111111)}; |
389 for (size_t i = 0; i < sizeof(data); i++) { | 389 for (size_t i = 0; i < sizeof(data); i++) { |
390 int length = 0; | 390 unsigned length = 0; |
391 decoder.Reset(data, data + i); | 391 decoder.Reset(data, data + i); |
392 decoder.checked_read_u32v(decoder.start(), 0, &length); | 392 decoder.checked_read_u32v(decoder.start(), 0, &length); |
393 EXPECT_EQ(i, length); | 393 EXPECT_EQ(i, length); |
394 EXPECT_FALSE(decoder.ok()); | 394 EXPECT_FALSE(decoder.ok()); |
395 } | 395 } |
396 } | 396 } |
397 | 397 |
398 TEST_F(DecoderTest, ReadU32v_off_end4) { | 398 TEST_F(DecoderTest, ReadU32v_off_end4) { |
399 static const byte data[] = {U32V_4(11111111)}; | 399 static const byte data[] = {U32V_4(11111111)}; |
400 for (size_t i = 0; i < sizeof(data); i++) { | 400 for (size_t i = 0; i < sizeof(data); i++) { |
401 int length = 0; | 401 unsigned length = 0; |
402 decoder.Reset(data, data + i); | 402 decoder.Reset(data, data + i); |
403 decoder.checked_read_u32v(decoder.start(), 0, &length); | 403 decoder.checked_read_u32v(decoder.start(), 0, &length); |
404 EXPECT_EQ(i, length); | 404 EXPECT_EQ(i, length); |
405 EXPECT_FALSE(decoder.ok()); | 405 EXPECT_FALSE(decoder.ok()); |
406 } | 406 } |
407 } | 407 } |
408 | 408 |
409 TEST_F(DecoderTest, ReadU32v_off_end5) { | 409 TEST_F(DecoderTest, ReadU32v_off_end5) { |
410 static const byte data[] = {U32V_5(111111111)}; | 410 static const byte data[] = {U32V_5(111111111)}; |
411 for (size_t i = 0; i < sizeof(data); i++) { | 411 for (size_t i = 0; i < sizeof(data); i++) { |
412 int length = 0; | 412 unsigned length = 0; |
413 decoder.Reset(data, data + i); | 413 decoder.Reset(data, data + i); |
414 decoder.checked_read_u32v(decoder.start(), 0, &length); | 414 decoder.checked_read_u32v(decoder.start(), 0, &length); |
415 EXPECT_EQ(i, length); | 415 EXPECT_EQ(i, length); |
416 EXPECT_FALSE(decoder.ok()); | 416 EXPECT_FALSE(decoder.ok()); |
417 } | 417 } |
418 } | 418 } |
419 | 419 |
420 TEST_F(DecoderTest, ReadU32v_extra_bits) { | 420 TEST_F(DecoderTest, ReadU32v_extra_bits) { |
421 byte data[] = {0x80, 0x80, 0x80, 0x80, 0x00}; | 421 byte data[] = {0x80, 0x80, 0x80, 0x80, 0x00}; |
422 for (int i = 1; i < 16; i++) { | 422 for (int i = 1; i < 16; i++) { |
423 data[4] = static_cast<byte>(i << 4); | 423 data[4] = static_cast<byte>(i << 4); |
424 int length = 0; | 424 unsigned length = 0; |
425 decoder.Reset(data, data + sizeof(data)); | 425 decoder.Reset(data, data + sizeof(data)); |
426 decoder.checked_read_u32v(decoder.start(), 0, &length); | 426 decoder.checked_read_u32v(decoder.start(), 0, &length); |
427 EXPECT_EQ(5, length); | 427 EXPECT_EQ(5, length); |
428 EXPECT_FALSE(decoder.ok()); | 428 EXPECT_FALSE(decoder.ok()); |
429 } | 429 } |
430 } | 430 } |
431 | 431 |
432 TEST_F(DecoderTest, ReadI32v_extra_bits_negative) { | 432 TEST_F(DecoderTest, ReadI32v_extra_bits_negative) { |
433 // OK for negative signed values to have extra ones. | 433 // OK for negative signed values to have extra ones. |
434 int length = 0; | 434 unsigned length = 0; |
435 byte data[] = {0xff, 0xff, 0xff, 0xff, 0x7f}; | 435 byte data[] = {0xff, 0xff, 0xff, 0xff, 0x7f}; |
436 decoder.Reset(data, data + sizeof(data)); | 436 decoder.Reset(data, data + sizeof(data)); |
437 decoder.checked_read_i32v(decoder.start(), 0, &length); | 437 decoder.checked_read_i32v(decoder.start(), 0, &length); |
438 EXPECT_EQ(5, length); | 438 EXPECT_EQ(5, length); |
439 EXPECT_TRUE(decoder.ok()); | 439 EXPECT_TRUE(decoder.ok()); |
440 } | 440 } |
441 | 441 |
442 TEST_F(DecoderTest, ReadI32v_extra_bits_positive) { | 442 TEST_F(DecoderTest, ReadI32v_extra_bits_positive) { |
443 // Not OK for positive signed values to have extra ones. | 443 // Not OK for positive signed values to have extra ones. |
444 int length = 0; | 444 unsigned length = 0; |
445 byte data[] = {0x80, 0x80, 0x80, 0x80, 0x77}; | 445 byte data[] = {0x80, 0x80, 0x80, 0x80, 0x77}; |
446 decoder.Reset(data, data + sizeof(data)); | 446 decoder.Reset(data, data + sizeof(data)); |
447 decoder.checked_read_i32v(decoder.start(), 0, &length); | 447 decoder.checked_read_i32v(decoder.start(), 0, &length); |
448 EXPECT_EQ(5, length); | 448 EXPECT_EQ(5, length); |
449 EXPECT_FALSE(decoder.ok()); | 449 EXPECT_FALSE(decoder.ok()); |
450 } | 450 } |
451 | 451 |
452 TEST_F(DecoderTest, ReadU32v_Bits) { | 452 TEST_F(DecoderTest, ReadU32v_Bits) { |
453 // A more exhaustive test. | 453 // A more exhaustive test. |
454 const int kMaxSize = 5; | 454 const int kMaxSize = 5; |
(...skipping 16 matching lines...) Expand all Loading... |
471 for (int j = 0; j < kMaxSize; j++) { | 471 for (int j = 0; j < kMaxSize; j++) { |
472 data[j] = static_cast<byte>((val >> (7 * j)) & MASK_7); | 472 data[j] = static_cast<byte>((val >> (7 * j)) & MASK_7); |
473 } | 473 } |
474 for (int j = 0; j < length - 1; j++) { | 474 for (int j = 0; j < length - 1; j++) { |
475 data[j] |= 0x80; | 475 data[j] |= 0x80; |
476 } | 476 } |
477 | 477 |
478 // foreach buffer size 0...5 | 478 // foreach buffer size 0...5 |
479 for (int limit = 0; limit <= kMaxSize; limit++) { | 479 for (int limit = 0; limit <= kMaxSize; limit++) { |
480 decoder.Reset(data, data + limit); | 480 decoder.Reset(data, data + limit); |
481 int rlen; | 481 unsigned rlen; |
482 uint32_t result = decoder.checked_read_u32v(data, 0, &rlen); | 482 uint32_t result = decoder.checked_read_u32v(data, 0, &rlen); |
483 if (limit < length) { | 483 if (limit < length) { |
484 EXPECT_FALSE(decoder.ok()); | 484 EXPECT_FALSE(decoder.ok()); |
485 } else { | 485 } else { |
486 EXPECT_TRUE(decoder.ok()); | 486 EXPECT_TRUE(decoder.ok()); |
487 EXPECT_EQ(val, result); | 487 EXPECT_EQ(val, result); |
488 EXPECT_EQ(length, rlen); | 488 EXPECT_EQ(length, rlen); |
489 } | 489 } |
490 } | 490 } |
491 } | 491 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 byte data[kMaxSize]; | 527 byte data[kMaxSize]; |
528 | 528 |
529 for (int i = 0; i < 64; i++) { | 529 for (int i = 0; i < 64; i++) { |
530 const uint64_t val = 1ull << i; | 530 const uint64_t val = 1ull << i; |
531 int index = i / 7; | 531 int index = i / 7; |
532 data[index] = 1 << (i % 7); | 532 data[index] = 1 << (i % 7); |
533 memset(data, 0x80, index); | 533 memset(data, 0x80, index); |
534 | 534 |
535 for (int limit = 0; limit <= kMaxSize; limit++) { | 535 for (int limit = 0; limit <= kMaxSize; limit++) { |
536 decoder.Reset(data, data + limit); | 536 decoder.Reset(data, data + limit); |
537 int length; | 537 unsigned length; |
538 uint64_t result = decoder.checked_read_u64v(data, 0, &length); | 538 uint64_t result = decoder.checked_read_u64v(data, 0, &length); |
539 if (limit <= index) { | 539 if (limit <= index) { |
540 EXPECT_FALSE(decoder.ok()); | 540 EXPECT_FALSE(decoder.ok()); |
541 } else { | 541 } else { |
542 EXPECT_TRUE(decoder.ok()); | 542 EXPECT_TRUE(decoder.ok()); |
543 EXPECT_EQ(val, result); | 543 EXPECT_EQ(val, result); |
544 EXPECT_EQ(index + 1, length); | 544 EXPECT_EQ(index + 1, length); |
545 } | 545 } |
546 } | 546 } |
547 } | 547 } |
(...skipping 20 matching lines...) Expand all Loading... |
568 for (int j = 0; j < kMaxSize; j++) { | 568 for (int j = 0; j < kMaxSize; j++) { |
569 data[j] = static_cast<byte>((val >> (7 * j)) & MASK_7); | 569 data[j] = static_cast<byte>((val >> (7 * j)) & MASK_7); |
570 } | 570 } |
571 for (int j = 0; j < length - 1; j++) { | 571 for (int j = 0; j < length - 1; j++) { |
572 data[j] |= 0x80; | 572 data[j] |= 0x80; |
573 } | 573 } |
574 | 574 |
575 // foreach buffer size 0...10 | 575 // foreach buffer size 0...10 |
576 for (int limit = 0; limit <= kMaxSize; limit++) { | 576 for (int limit = 0; limit <= kMaxSize; limit++) { |
577 decoder.Reset(data, data + limit); | 577 decoder.Reset(data, data + limit); |
578 int rlen; | 578 unsigned rlen; |
579 uint64_t result = decoder.checked_read_u64v(data, 0, &rlen); | 579 uint64_t result = decoder.checked_read_u64v(data, 0, &rlen); |
580 if (limit < length) { | 580 if (limit < length) { |
581 EXPECT_FALSE(decoder.ok()); | 581 EXPECT_FALSE(decoder.ok()); |
582 } else { | 582 } else { |
583 EXPECT_TRUE(decoder.ok()); | 583 EXPECT_TRUE(decoder.ok()); |
584 EXPECT_EQ(val, result); | 584 EXPECT_EQ(val, result); |
585 EXPECT_EQ(length, rlen); | 585 EXPECT_EQ(length, rlen); |
586 } | 586 } |
587 } | 587 } |
588 } | 588 } |
(...skipping 21 matching lines...) Expand all Loading... |
610 for (int j = 0; j < kMaxSize; j++) { | 610 for (int j = 0; j < kMaxSize; j++) { |
611 data[j] = static_cast<byte>((val >> (7 * j)) & MASK_7); | 611 data[j] = static_cast<byte>((val >> (7 * j)) & MASK_7); |
612 } | 612 } |
613 for (int j = 0; j < length - 1; j++) { | 613 for (int j = 0; j < length - 1; j++) { |
614 data[j] |= 0x80; | 614 data[j] |= 0x80; |
615 } | 615 } |
616 | 616 |
617 // foreach buffer size 0...10 | 617 // foreach buffer size 0...10 |
618 for (int limit = 0; limit <= kMaxSize; limit++) { | 618 for (int limit = 0; limit <= kMaxSize; limit++) { |
619 decoder.Reset(data, data + limit); | 619 decoder.Reset(data, data + limit); |
620 int rlen; | 620 unsigned rlen; |
621 int64_t result = decoder.checked_read_i64v(data, 0, &rlen); | 621 int64_t result = decoder.checked_read_i64v(data, 0, &rlen); |
622 if (limit < length) { | 622 if (limit < length) { |
623 EXPECT_FALSE(decoder.ok()); | 623 EXPECT_FALSE(decoder.ok()); |
624 } else { | 624 } else { |
625 EXPECT_TRUE(decoder.ok()); | 625 EXPECT_TRUE(decoder.ok()); |
626 EXPECT_EQ(val, result); | 626 EXPECT_EQ(val, result); |
627 EXPECT_EQ(length, rlen); | 627 EXPECT_EQ(length, rlen); |
628 } | 628 } |
629 } | 629 } |
630 } | 630 } |
631 } | 631 } |
632 } | 632 } |
633 | 633 |
634 TEST_F(DecoderTest, ReadU64v_extra_bits) { | 634 TEST_F(DecoderTest, ReadU64v_extra_bits) { |
635 byte data[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00}; | 635 byte data[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00}; |
636 for (int i = 1; i < 128; i++) { | 636 for (int i = 1; i < 128; i++) { |
637 data[9] = static_cast<byte>(i << 1); | 637 data[9] = static_cast<byte>(i << 1); |
638 int length = 0; | 638 unsigned length = 0; |
639 decoder.Reset(data, data + sizeof(data)); | 639 decoder.Reset(data, data + sizeof(data)); |
640 decoder.checked_read_u64v(decoder.start(), 0, &length); | 640 decoder.checked_read_u64v(decoder.start(), 0, &length); |
641 EXPECT_EQ(10, length); | 641 EXPECT_EQ(10, length); |
642 EXPECT_FALSE(decoder.ok()); | 642 EXPECT_FALSE(decoder.ok()); |
643 } | 643 } |
644 } | 644 } |
645 | 645 |
646 TEST_F(DecoderTest, ReadI64v_extra_bits_negative) { | 646 TEST_F(DecoderTest, ReadI64v_extra_bits_negative) { |
647 // OK for negative signed values to have extra ones. | 647 // OK for negative signed values to have extra ones. |
648 int length = 0; | 648 unsigned length = 0; |
649 byte data[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; | 649 byte data[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; |
650 decoder.Reset(data, data + sizeof(data)); | 650 decoder.Reset(data, data + sizeof(data)); |
651 decoder.checked_read_i64v(decoder.start(), 0, &length); | 651 decoder.checked_read_i64v(decoder.start(), 0, &length); |
652 EXPECT_EQ(10, length); | 652 EXPECT_EQ(10, length); |
653 EXPECT_TRUE(decoder.ok()); | 653 EXPECT_TRUE(decoder.ok()); |
654 } | 654 } |
655 | 655 |
656 TEST_F(DecoderTest, ReadI64v_extra_bits_positive) { | 656 TEST_F(DecoderTest, ReadI64v_extra_bits_positive) { |
657 // Not OK for positive signed values to have extra ones. | 657 // Not OK for positive signed values to have extra ones. |
658 int length = 0; | 658 unsigned length = 0; |
659 byte data[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x77}; | 659 byte data[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x77}; |
660 decoder.Reset(data, data + sizeof(data)); | 660 decoder.Reset(data, data + sizeof(data)); |
661 decoder.checked_read_i64v(decoder.start(), 0, &length); | 661 decoder.checked_read_i64v(decoder.start(), 0, &length); |
662 EXPECT_EQ(10, length); | 662 EXPECT_EQ(10, length); |
663 EXPECT_FALSE(decoder.ok()); | 663 EXPECT_FALSE(decoder.ok()); |
664 } | 664 } |
665 | 665 |
666 } // namespace wasm | 666 } // namespace wasm |
667 } // namespace internal | 667 } // namespace internal |
668 } // namespace v8 | 668 } // namespace v8 |
OLD | NEW |