Index: test/unittests/wasm/decoder-unittest.cc |
diff --git a/test/unittests/wasm/decoder-unittest.cc b/test/unittests/wasm/decoder-unittest.cc |
index de6bf49ea855fd5aa07ae27b7f0ca4971c967558..d773c955c0454e629d7ac501d02971a9352edc53 100644 |
--- a/test/unittests/wasm/decoder-unittest.cc |
+++ b/test/unittests/wasm/decoder-unittest.cc |
@@ -38,6 +38,26 @@ class DecoderTest : public TestWithZone { |
EXPECT_EQ(expected_length, length); \ |
} while (false) |
+#define CHECK_UINT64V_INLINE(expected, expected_length, ...) \ |
+ do { \ |
+ const byte data[] = {__VA_ARGS__}; \ |
+ decoder.Reset(data, data + sizeof(data)); \ |
+ int length; \ |
+ EXPECT_EQ(expected, \ |
+ decoder.checked_read_u64v(decoder.start(), 0, &length)); \ |
+ EXPECT_EQ(expected_length, length); \ |
+ } while (false) |
+ |
+#define CHECK_INT64V_INLINE(expected, expected_length, ...) \ |
+ do { \ |
+ const byte data[] = {__VA_ARGS__}; \ |
+ decoder.Reset(data, data + sizeof(data)); \ |
+ int length; \ |
+ EXPECT_EQ(expected, \ |
+ decoder.checked_read_i64v(decoder.start(), 0, &length)); \ |
+ EXPECT_EQ(expected_length, length); \ |
+ } while (false) |
+ |
TEST_F(DecoderTest, ReadU32v_OneByte) { |
CHECK_UINT32V_INLINE(0, 1, 0); |
CHECK_UINT32V_INLINE(5, 1, 5); |
@@ -408,6 +428,201 @@ TEST_F(DecoderTest, ReadU32v_extra_bits) { |
} |
} |
+TEST_F(DecoderTest, ReadU32v_Bits) { |
+ // A more exhaustive test. |
+ const int kMaxSize = 5; |
+ const uint32_t kVals[] = { |
+ 0xaabbccdd, 0x11223344, 0x33445566, 0xffeeddcc, 0xF0F0F0F0, 0x0F0F0F0F, |
+ 0xEEEEEEEE, 0xAAAAAAAA, 0x12345678, 0x9abcdef0, 0x80309488, 0x729ed997, |
+ 0xc4a0cf81, 0x16c6eb85, 0x4206db8e, 0xf3b089d5, 0xaa2e223e, 0xf99e29c8, |
+ 0x4a4357d8, 0x1890b1c1, 0x8d80a085, 0xacb6ae4c, 0x1b827e10, 0xeb5c7bd9, |
+ 0xbb1bc146, 0xdf57a33l}; |
+ byte data[kMaxSize]; |
+ |
+ // foreach value in above array |
+ for (size_t v = 0; v < arraysize(kVals); v++) { |
+ // foreach length 1...32 |
+ for (int i = 1; i <= 32; i++) { |
+ uint32_t val = kVals[v]; |
+ if (i < 32) val &= ((1 << i) - 1); |
+ |
+ int length = 1 + i / 7; |
+ for (int j = 0; j < kMaxSize; j++) { |
+ data[j] = static_cast<byte>((val >> (7 * j)) & MASK_7); |
+ } |
+ for (int j = 0; j < length - 1; j++) { |
+ data[j] |= 0x80; |
+ } |
+ |
+ // foreach buffer size 0...5 |
+ for (int limit = 0; limit <= kMaxSize; limit++) { |
+ decoder.Reset(data, data + limit); |
+ int rlen; |
+ uint32_t result = decoder.checked_read_u32v(data, 0, &rlen); |
+ if (limit < length) { |
+ EXPECT_FALSE(decoder.ok()); |
+ } else { |
+ EXPECT_TRUE(decoder.ok()); |
+ EXPECT_EQ(val, result); |
+ EXPECT_EQ(length, rlen); |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+TEST_F(DecoderTest, ReadU64v_OneByte) { |
+ CHECK_UINT64V_INLINE(0, 1, 0); |
+ CHECK_UINT64V_INLINE(6, 1, 6); |
+ CHECK_UINT64V_INLINE(8, 1, 8); |
+ CHECK_UINT64V_INLINE(12, 1, 12); |
+ CHECK_UINT64V_INLINE(33, 1, 33); |
+ CHECK_UINT64V_INLINE(59, 1, 59); |
+ CHECK_UINT64V_INLINE(110, 1, 110); |
+ CHECK_UINT64V_INLINE(125, 1, 125); |
+ CHECK_UINT64V_INLINE(126, 1, 126); |
+ CHECK_UINT64V_INLINE(127, 1, 127); |
+} |
+ |
+TEST_F(DecoderTest, ReadI64v_OneByte) { |
+ CHECK_INT64V_INLINE(0, 1, 0); |
+ CHECK_INT64V_INLINE(4, 1, 4); |
+ CHECK_INT64V_INLINE(6, 1, 6); |
+ CHECK_INT64V_INLINE(9, 1, 9); |
+ CHECK_INT64V_INLINE(33, 1, 33); |
+ CHECK_INT64V_INLINE(61, 1, 61); |
+ CHECK_INT64V_INLINE(63, 1, 63); |
+ |
+ CHECK_INT64V_INLINE(-1, 1, 127); |
+ CHECK_INT64V_INLINE(-2, 1, 126); |
+ CHECK_INT64V_INLINE(-11, 1, 117); |
+ CHECK_INT64V_INLINE(-62, 1, 66); |
+ CHECK_INT64V_INLINE(-63, 1, 65); |
+ CHECK_INT64V_INLINE(-64, 1, 64); |
+} |
+ |
+TEST_F(DecoderTest, ReadU64v_PowerOf2) { |
+ const int kMaxSize = 10; |
+ byte data[kMaxSize]; |
+ |
+ for (int i = 0; i < 64; i++) { |
+ const uint64_t val = 1ull << i; |
+ int index = i / 7; |
+ data[index] = 1 << (i % 7); |
+ memset(data, 0x80, index); |
+ |
+ for (int limit = 0; limit <= kMaxSize; limit++) { |
+ decoder.Reset(data, data + limit); |
+ int length; |
+ uint64_t result = decoder.checked_read_u64v(data, 0, &length); |
+ if (limit <= index) { |
+ EXPECT_FALSE(decoder.ok()); |
+ } else { |
+ EXPECT_TRUE(decoder.ok()); |
+ EXPECT_EQ(val, result); |
+ EXPECT_EQ(index + 1, length); |
+ } |
+ } |
+ } |
+} |
+ |
+TEST_F(DecoderTest, ReadU64v_Bits) { |
+ const int kMaxSize = 10; |
+ const uint64_t kVals[] = { |
+ 0xaabbccdd11223344ull, 0x33445566ffeeddccull, 0xF0F0F0F0F0F0F0F0ull, |
+ 0x0F0F0F0F0F0F0F0Full, 0xEEEEEEEEEEEEEEEEull, 0xAAAAAAAAAAAAAAAAull, |
+ 0x123456789abcdef0ull, 0x80309488729ed997ull, 0xc4a0cf8116c6eb85ull, |
+ 0x4206db8ef3b089d5ull, 0xaa2e223ef99e29c8ull, 0x4a4357d81890b1c1ull, |
+ 0x8d80a085acb6ae4cull, 0x1b827e10eb5c7bd9ull, 0xbb1bc146df57a338ull}; |
+ byte data[kMaxSize]; |
+ |
+ // foreach value in above array |
+ for (size_t v = 0; v < arraysize(kVals); v++) { |
+ // foreach length 1...64 |
+ for (int i = 1; i <= 64; i++) { |
+ uint64_t val = kVals[v]; |
+ if (i < 64) val &= ((1ull << i) - 1); |
+ |
+ int length = 1 + i / 7; |
+ for (int j = 0; j < kMaxSize; j++) { |
+ data[j] = static_cast<byte>((val >> (7 * j)) & MASK_7); |
+ } |
+ for (int j = 0; j < length - 1; j++) { |
+ data[j] |= 0x80; |
+ } |
+ |
+ // foreach buffer size 0...10 |
+ for (int limit = 0; limit <= kMaxSize; limit++) { |
+ decoder.Reset(data, data + limit); |
+ int rlen; |
+ uint64_t result = decoder.checked_read_u64v(data, 0, &rlen); |
+ if (limit < length) { |
+ EXPECT_FALSE(decoder.ok()); |
+ } else { |
+ EXPECT_TRUE(decoder.ok()); |
+ EXPECT_EQ(val, result); |
+ EXPECT_EQ(length, rlen); |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+TEST_F(DecoderTest, ReadI64v_Bits) { |
+ const int kMaxSize = 10; |
+ // Exhaustive signedness test. |
+ const uint64_t kVals[] = { |
+ 0xaabbccdd11223344ull, 0x33445566ffeeddccull, 0xF0F0F0F0F0F0F0F0ull, |
+ 0x0F0F0F0F0F0F0F0Full, 0xEEEEEEEEEEEEEEEEull, 0xAAAAAAAAAAAAAAAAull, |
+ 0x123456789abcdef0ull, 0x80309488729ed997ull, 0xc4a0cf8116c6eb85ull, |
+ 0x4206db8ef3b089d5ull, 0xaa2e223ef99e29c8ull, 0x4a4357d81890b1c1ull, |
+ 0x8d80a085acb6ae4cull, 0x1b827e10eb5c7bd9ull, 0xbb1bc146df57a338ull}; |
+ byte data[kMaxSize]; |
+ |
+ // foreach value in above array |
+ for (size_t v = 0; v < arraysize(kVals); v++) { |
+ // foreach length 1...64 |
+ for (int i = 1; i <= 64; i++) { |
+ const int64_t val = bit_cast<int64_t>(kVals[v] << (64 - i)) >> (64 - i); |
+ |
+ int length = 1 + i / 7; |
+ for (int j = 0; j < kMaxSize; j++) { |
+ const uint64_t uval = bit_cast<uint64_t>(val); |
+ data[j] = static_cast<byte>((uval >> (7 * j)) & MASK_7); |
+ } |
+ for (int j = 0; j < length - 1; j++) { |
+ data[j] |= 0x80; |
+ } |
+ |
+ // foreach buffer size 0...10 |
+ for (int limit = 0; limit <= kMaxSize; limit++) { |
+ decoder.Reset(data, data + limit); |
+ int rlen; |
+ int64_t result = decoder.checked_read_i64v(data, 0, &rlen); |
+ if (limit < length) { |
+ EXPECT_FALSE(decoder.ok()); |
+ } else { |
+ EXPECT_TRUE(decoder.ok()); |
+ EXPECT_EQ(val, result); |
+ EXPECT_EQ(length, rlen); |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+TEST_F(DecoderTest, ReadU64v_extra_bits) { |
+ byte data[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00}; |
+ for (int i = 1; i < 128; i++) { |
+ data[9] = static_cast<byte>(i << 1); |
+ int length = 0; |
+ decoder.Reset(data, data + sizeof(data)); |
+ decoder.checked_read_u64v(decoder.start(), 0, &length); |
+ EXPECT_EQ(10, length); |
+ EXPECT_FALSE(decoder.ok()); |
+ } |
+} |
+ |
} // namespace wasm |
} // namespace internal |
} // namespace v8 |