WebKit Bugzilla
Attachment 347632 Details for
Bug 188788
: LEBDecoder and Wasm::Parser should be tolerant for not enough data
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188788-20180821213540.patch (text/plain), 49.93 KB, created by
Yusuke Suzuki
on 2018-08-21 05:35:42 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2018-08-21 05:35:42 PDT
Size:
49.93 KB
patch
obsolete
>Subversion Revision: 235110 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index ea61d673cd31c627ba7f2a35938cbd704005e2c7..00e31587682c9f7303ec2f19db099a4a28f1b463 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,35 @@ >+2018-08-21 Yusuke Suzuki <yusukesuzuki@slowstart.org> >+ >+ LEBDecoder and Wasm::Parser should be tolerant for not enough data >+ https://bugs.webkit.org/show_bug.cgi?id=188788 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Wasm::Parser should be tolerant for non-enough data. It means that >+ parser should return two types of errors, recoverable and fatal. >+ If a fatal error happens, we cannot restart parsing even if we have >+ more subsequent data. But recoverable error means that we may succeed >+ parsing if we have more subsequent data. These parsing function should >+ be the basis of streaming wasm decoding. >+ >+ * wasm/WasmParser.h: >+ (JSC::Wasm::Parser<SuccessType>::consumeCharacter): >+ (JSC::Wasm::Parser<SuccessType>::consumeString): >+ (JSC::Wasm::Parser<SuccessType>::consumeUTF8String): >+ (JSC::Wasm::Parser<SuccessType>::parseVarUInt32): >+ (JSC::Wasm::Parser<SuccessType>::parseVarUInt64): >+ (JSC::Wasm::Parser<SuccessType>::parseVarInt32): >+ (JSC::Wasm::Parser<SuccessType>::parseVarInt64): >+ (JSC::Wasm::Parser<SuccessType>::parseUInt32): >+ (JSC::Wasm::Parser<SuccessType>::parseUInt64): >+ (JSC::Wasm::Parser<SuccessType>::parseUInt8): >+ (JSC::Wasm::Parser<SuccessType>::parseInt7): >+ (JSC::Wasm::Parser<SuccessType>::parseUInt7): >+ (JSC::Wasm::Parser<SuccessType>::parseVarUInt1): >+ (JSC::Wasm::Parser<SuccessType>::parseResultType): >+ (JSC::Wasm::Parser<SuccessType>::parseValueType): >+ (JSC::Wasm::Parser<SuccessType>::parseExternalKind): >+ > 2018-08-21 Saam barati <sbarati@apple.com> > > JSRunLoopTimer may run part of a member function after it's destroyed >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index d5ead37e665fad5edaed0881b9c9197cf504b3cb..69f36aae38e41cd7e2ee0505b1791f5239aedfc4 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,25 @@ >+2018-08-21 Yusuke Suzuki <yusukesuzuki@slowstart.org> >+ >+ LEBDecoder and Wasm::Parser should be tolerant for not enough data >+ https://bugs.webkit.org/show_bug.cgi?id=188788 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ LEBDecoder returns Expected<void, StreamingError>, which indicates whether the error of decoding is recoverable. >+ This is useful for streaming wasm decoding. >+ >+ * WTF.xcodeproj/project.pbxproj: >+ * wtf/CMakeLists.txt: >+ * wtf/LEBDecoder.h: >+ (WTF::LEBDecoder::decodeUInt): >+ (WTF::LEBDecoder::decodeInt): >+ (WTF::LEBDecoder::decodeUInt32): >+ (WTF::LEBDecoder::decodeUInt64): >+ (WTF::LEBDecoder::decodeInt32): >+ (WTF::LEBDecoder::decodeInt64): >+ * wtf/StreamingError.h: Added. >+ Add new enum class StreamingError, which has Recoverable and Fatal types. >+ > 2018-08-20 Saam barati <sbarati@apple.com> > > Inline DataView accesses into DFG/FTL >diff --git a/Source/JavaScriptCore/wasm/WasmParser.h b/Source/JavaScriptCore/wasm/WasmParser.h >index 6510705eaf578ce33e3bd76b2bc838adda5f5b00..94c87ebaae6642132417563635ae438f34eabb0f 100644 >--- a/Source/JavaScriptCore/wasm/WasmParser.h >+++ b/Source/JavaScriptCore/wasm/WasmParser.h >@@ -58,28 +58,30 @@ class Parser { > typedef Expected<void, ErrorType> PartialResult; > typedef Expected<SuccessType, ErrorType> Result; > >+ using ConsumeResult = WTF::LEBDecoder::Result; >+ > protected: > Parser(const uint8_t*, size_t); > >- bool WARN_UNUSED_RETURN consumeCharacter(char); >- bool WARN_UNUSED_RETURN consumeString(const char*); >- bool WARN_UNUSED_RETURN consumeUTF8String(Name&, size_t); >+ ConsumeResult WARN_UNUSED_RETURN consumeCharacter(char); >+ ConsumeResult WARN_UNUSED_RETURN consumeString(const char*); >+ ConsumeResult WARN_UNUSED_RETURN consumeUTF8String(Name&, size_t); > >- bool WARN_UNUSED_RETURN parseVarUInt1(uint8_t&); >- bool WARN_UNUSED_RETURN parseInt7(int8_t&); >- bool WARN_UNUSED_RETURN parseUInt7(uint8_t&); >- bool WARN_UNUSED_RETURN parseUInt8(uint8_t&); >- bool WARN_UNUSED_RETURN parseUInt32(uint32_t&); >- bool WARN_UNUSED_RETURN parseUInt64(uint64_t&); >- bool WARN_UNUSED_RETURN parseVarUInt32(uint32_t&); >- bool WARN_UNUSED_RETURN parseVarUInt64(uint64_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseVarUInt1(uint8_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseInt7(int8_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseUInt7(uint8_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseUInt8(uint8_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseUInt32(uint32_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseUInt64(uint64_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseVarUInt32(uint32_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseVarUInt64(uint64_t&); > >- bool WARN_UNUSED_RETURN parseVarInt32(int32_t&); >- bool WARN_UNUSED_RETURN parseVarInt64(int64_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseVarInt32(int32_t&); >+ ConsumeResult WARN_UNUSED_RETURN parseVarInt64(int64_t&); > >- bool WARN_UNUSED_RETURN parseResultType(Type&); >- bool WARN_UNUSED_RETURN parseValueType(Type&); >- bool WARN_UNUSED_RETURN parseExternalKind(ExternalKind&); >+ ConsumeResult WARN_UNUSED_RETURN parseResultType(Type&); >+ ConsumeResult WARN_UNUSED_RETURN parseValueType(Type&); >+ ConsumeResult WARN_UNUSED_RETURN parseExternalKind(ExternalKind&); > > const uint8_t* source() const { return m_source; } > size_t length() const { return m_sourceLength; } >@@ -116,41 +118,42 @@ ALWAYS_INLINE Parser<SuccessType>::Parser(const uint8_t* sourceBuffer, size_t so > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::consumeCharacter(char c) >+ALWAYS_INLINE auto Parser<SuccessType>::consumeCharacter(char c) -> ConsumeResult > { > if (m_offset >= length()) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > if (c == source()[m_offset]) { > m_offset++; >- return true; >+ return { }; > } >- return false; >+ return makeUnexpected(StreamingError::Fatal); > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::consumeString(const char* str) >+ALWAYS_INLINE auto Parser<SuccessType>::consumeString(const char* str) -> ConsumeResult > { > unsigned start = m_offset; > if (m_offset >= length()) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > for (size_t i = 0; str[i]; i++) { >- if (!consumeCharacter(str[i])) { >+ auto consumeResult = consumeCharacter(str[i]); >+ if (!consumeResult) { > m_offset = start; >- return false; >+ return consumeResult; > } > } >- return true; >+ return { }; > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::consumeUTF8String(Name& result, size_t stringLength) >+ALWAYS_INLINE auto Parser<SuccessType>::consumeUTF8String(Name& result, size_t stringLength) -> ConsumeResult > { > if (length() < stringLength || m_offset > length() - stringLength) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > if (stringLength > maxStringSize) >- return false; >+ return makeUnexpected(StreamingError::Fatal); > if (!result.tryReserveCapacity(stringLength)) >- return false; >+ return makeUnexpected(StreamingError::Fatal); > > const uint8_t* stringStart = source() + m_offset; > >@@ -162,127 +165,139 @@ ALWAYS_INLINE bool Parser<SuccessType>::consumeUTF8String(Name& result, size_t s > UChar* bufferCurrent = bufferStart; > const char* stringCurrent = reinterpret_cast<const char*>(stringStart); > if (WTF::Unicode::convertUTF8ToUTF16(&stringCurrent, reinterpret_cast<const char *>(stringStart + stringLength), &bufferCurrent, bufferCurrent + buffer.size()) != WTF::Unicode::conversionOK) >- return false; >+ return makeUnexpected(StreamingError::Fatal); > } > > result.grow(stringLength); > memcpy(result.data(), stringStart, stringLength); > m_offset += stringLength; >- return true; >+ return { }; > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseVarUInt32(uint32_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseVarUInt32(uint32_t& result) -> ConsumeResult > { > return WTF::LEBDecoder::decodeUInt32(m_source, m_sourceLength, m_offset, result); > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseVarUInt64(uint64_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseVarUInt64(uint64_t& result) -> ConsumeResult > { > return WTF::LEBDecoder::decodeUInt64(m_source, m_sourceLength, m_offset, result); > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseVarInt32(int32_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseVarInt32(int32_t& result) -> ConsumeResult > { > return WTF::LEBDecoder::decodeInt32(m_source, m_sourceLength, m_offset, result); > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseVarInt64(int64_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseVarInt64(int64_t& result) -> ConsumeResult > { > return WTF::LEBDecoder::decodeInt64(m_source, m_sourceLength, m_offset, result); > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseUInt32(uint32_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseUInt32(uint32_t& result) -> ConsumeResult > { > if (length() < 4 || m_offset > length() - 4) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > result = *reinterpret_cast<const uint32_t*>(source() + m_offset); > m_offset += 4; >- return true; >+ return { }; > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseUInt64(uint64_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseUInt64(uint64_t& result) -> ConsumeResult > { > if (length() < 8 || m_offset > length() - 8) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > result = *reinterpret_cast<const uint64_t*>(source() + m_offset); > m_offset += 8; >- return true; >+ return { }; > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseUInt8(uint8_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseUInt8(uint8_t& result) -> ConsumeResult > { > if (m_offset >= length()) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > result = source()[m_offset++]; >- return true; >+ return { }; > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseInt7(int8_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseInt7(int8_t& result) -> ConsumeResult > { > if (m_offset >= length()) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > uint8_t v = source()[m_offset++]; > result = (v & 0x40) ? WTF::bitwise_cast<int8_t>(uint8_t(v | 0x80)) : v; >- return (v & 0x80) == 0; >+ if ((v & 0x80) == 0) >+ return { }; >+ return makeUnexpected(StreamingError::Fatal); > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseUInt7(uint8_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseUInt7(uint8_t& result) -> ConsumeResult > { > if (m_offset >= length()) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > result = source()[m_offset++]; >- return result < 0x80; >+ if (result < 0x80) >+ return { }; >+ return makeUnexpected(StreamingError::Fatal); > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseVarUInt1(uint8_t& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseVarUInt1(uint8_t& result) -> ConsumeResult > { > uint32_t temp; >- if (!parseVarUInt32(temp)) >- return false; >+ auto parseResult = parseVarUInt32(temp); >+ if (!parseResult) >+ return parseResult; > if (temp > 1) >- return false; >+ return makeUnexpected(StreamingError::Fatal); > result = static_cast<uint8_t>(temp); >- return true; >+ return { }; > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseResultType(Type& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseResultType(Type& result) -> ConsumeResult > { > int8_t value; >- if (!parseInt7(value)) >- return false; >+ auto parseResult = parseInt7(value); >+ if (!parseResult) >+ return parseResult; > if (!isValidType(value)) >- return false; >+ return makeUnexpected(StreamingError::Fatal); > result = static_cast<Type>(value); >- return true; >+ return { }; > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseValueType(Type& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseValueType(Type& result) -> ConsumeResult > { >- return parseResultType(result) && isValueType(result); >+ auto parseResult = parseResultType(result); >+ if (!parseResult) >+ return parseResult; >+ if (!isValueType(result)) >+ return makeUnexpected(StreamingError::Fatal); >+ return { }; > } > > template<typename SuccessType> >-ALWAYS_INLINE bool Parser<SuccessType>::parseExternalKind(ExternalKind& result) >+ALWAYS_INLINE auto Parser<SuccessType>::parseExternalKind(ExternalKind& result) -> ConsumeResult > { > uint8_t value; >- if (!parseUInt7(value)) >- return false; >+ auto parseResult = parseUInt7(value); >+ if (!parseResult) >+ return parseResult; > if (!isValidExternalKind(value)) >- return false; >+ return makeUnexpected(StreamingError::Fatal); > result = static_cast<ExternalKind>(value); >- return true; >+ return { }; > } > > } } // namespace JSC::Wasm >diff --git a/Source/WTF/WTF.xcodeproj/project.pbxproj b/Source/WTF/WTF.xcodeproj/project.pbxproj >index 45b5ceaecf0e02ec5d65167787675c689d35245d..a7f20deb2426a1e3afbea034b9ae4db6eaff4c2f 100644 >--- a/Source/WTF/WTF.xcodeproj/project.pbxproj >+++ b/Source/WTF/WTF.xcodeproj/project.pbxproj >@@ -362,6 +362,7 @@ > 5311BD5B1EA822F900525281 /* ThreadMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadMessage.cpp; sourceTree = "<group>"; }; > 53534F291EC0E10E00141B2F /* MachExceptions.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = MachExceptions.defs; sourceTree = "<group>"; }; > 539EB0621D55284200C82EF7 /* LEBDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LEBDecoder.h; sourceTree = "<group>"; }; >+ 5D5ED35CEBF5440580FA0D40 /* StreamingError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamingError.h; sourceTree = "<group>"; }; > 53EC253C1E95AD30000831B9 /* PriorityQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PriorityQueue.h; sourceTree = "<group>"; }; > 53F08A1BA39D49A8BAD369A1 /* StdSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StdSet.h; sourceTree = "<group>"; }; > 53F1D98620477B9800EBC6BF /* FunctionTraits.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = FunctionTraits.h; sourceTree = "<group>"; }; >@@ -1094,6 +1095,7 @@ > 132743924FC54E469F5A8E6E /* StdUnorderedSet.h */, > C4F8A93619C65EB400B2B15D /* Stopwatch.h */, > 1A6BB768162F300500DD16DB /* StreamBuffer.h */, >+ 5D5ED35CEBF5440580FA0D40 /* StreamingError.h */, > A8A47313151A825B004123FF /* StringExtras.h */, > A748745117A0BDAE00FA04CB /* StringHashDumpContext.h */, > 0FDDBFA51666DFA300C55FEF /* StringPrintStream.cpp */, >diff --git a/Source/WTF/wtf/CMakeLists.txt b/Source/WTF/wtf/CMakeLists.txt >index 9adb55543d013fea9af5a7aae49432f95f3240f2..0607e591fa441596adc4627e15cab0c853e7fcf7 100644 >--- a/Source/WTF/wtf/CMakeLists.txt >+++ b/Source/WTF/wtf/CMakeLists.txt >@@ -221,6 +221,7 @@ set(WTF_PUBLIC_HEADERS > StdUnorderedSet.h > Stopwatch.h > StreamBuffer.h >+ StreamingError.h > StringExtras.h > StringHashDumpContext.h > StringPrintStream.h >diff --git a/Source/WTF/wtf/LEBDecoder.h b/Source/WTF/wtf/LEBDecoder.h >index 9462770c699cd05ea6573e3ed9c1c975a8b51507..fbe1e9f1fe42524bf11815bde5f27a47c3bcd923 100644 >--- a/Source/WTF/wtf/LEBDecoder.h >+++ b/Source/WTF/wtf/LEBDecoder.h >@@ -26,6 +26,8 @@ > #pragma once > > #include "Compiler.h" >+#include "Expected.h" >+#include "StreamingError.h" > #include <algorithm> > #include <limits.h> > >@@ -35,72 +37,84 @@ > > namespace WTF { namespace LEBDecoder { > >+using Result = Expected<void, StreamingError>; >+ > template<typename T> >-inline bool WARN_UNUSED_RETURN decodeUInt(const uint8_t* bytes, size_t length, size_t& offset, T& result) >+inline Result WARN_UNUSED_RETURN decodeUInt(const uint8_t* bytes, size_t length, size_t& offset, T& result) > { >- const size_t numBits = sizeof(T) * CHAR_BIT; >- const size_t maxByteLength = (numBits - 1) / 7 + 1; // numBits / 7 rounding up. >+ constexpr size_t numBits = sizeof(T) * CHAR_BIT; >+ constexpr size_t maxByteLength = (numBits - 1) / 7 + 1; // numBits / 7 rounding up. > if (length <= offset) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > result = 0; > unsigned shift = 0; > size_t last = std::min(maxByteLength, length - offset) - 1; >+ size_t start = offset; > for (unsigned i = 0; true; ++i) { > uint8_t byte = bytes[offset++]; > result |= static_cast<T>(byte & 0x7f) << shift; > shift += 7; > if (!(byte & 0x80)) >- return true; >- if (i == last) >- return false; >+ return { }; >+ if (i == last) { >+ offset = start; >+ if (i == (maxByteLength - 1)) >+ return makeUnexpected(StreamingError::Fatal); >+ return makeUnexpected(StreamingError::Recoverable); >+ } > } > RELEASE_ASSERT_NOT_REACHED(); >- return true; >+ return { }; > } > > template<typename T> >-inline bool WARN_UNUSED_RETURN decodeInt(const uint8_t* bytes, size_t length, size_t& offset, T& result) >+inline Result WARN_UNUSED_RETURN decodeInt(const uint8_t* bytes, size_t length, size_t& offset, T& result) > { >- const size_t numBits = sizeof(T) * CHAR_BIT; >- const size_t maxByteLength = (numBits - 1) / 7 + 1; // numBits / 7 rounding up. >+ constexpr size_t numBits = sizeof(T) * CHAR_BIT; >+ constexpr size_t maxByteLength = (numBits - 1) / 7 + 1; // numBits / 7 rounding up. > if (length <= offset) >- return false; >+ return makeUnexpected(StreamingError::Recoverable); > result = 0; > unsigned shift = 0; > size_t last = std::min(maxByteLength, length - offset) - 1; > uint8_t byte; >+ size_t start = offset; > for (unsigned i = 0; true; ++i) { > byte = bytes[offset++]; > result |= static_cast<T>(byte & 0x7f) << shift; > shift += 7; > if (!(byte & 0x80)) > break; >- if (i == last) >- return false; >+ if (i == last) { >+ offset = start; >+ if (i == (maxByteLength - 1)) >+ return makeUnexpected(StreamingError::Fatal); >+ return makeUnexpected(StreamingError::Recoverable); >+ } > } > > using UnsignedT = typename std::make_unsigned<T>::type; > if (shift < numBits && (byte & 0x40)) > result = static_cast<T>(static_cast<UnsignedT>(result) | (static_cast<UnsignedT>(-1) << shift)); >- return true; >+ return { }; > } > >-inline bool WARN_UNUSED_RETURN decodeUInt32(const uint8_t* bytes, size_t length, size_t& offset, uint32_t& result) >+inline Result WARN_UNUSED_RETURN decodeUInt32(const uint8_t* bytes, size_t length, size_t& offset, uint32_t& result) > { > return decodeUInt<uint32_t>(bytes, length, offset, result); > } > >-inline bool WARN_UNUSED_RETURN decodeUInt64(const uint8_t* bytes, size_t length, size_t& offset, uint64_t& result) >+inline Result WARN_UNUSED_RETURN decodeUInt64(const uint8_t* bytes, size_t length, size_t& offset, uint64_t& result) > { > return decodeUInt<uint64_t>(bytes, length, offset, result); > } > >-inline bool WARN_UNUSED_RETURN decodeInt32(const uint8_t* bytes, size_t length, size_t& offset, int32_t& result) >+inline Result WARN_UNUSED_RETURN decodeInt32(const uint8_t* bytes, size_t length, size_t& offset, int32_t& result) > { > return decodeInt<int32_t>(bytes, length, offset, result); > } > >-inline bool WARN_UNUSED_RETURN decodeInt64(const uint8_t* bytes, size_t length, size_t& offset, int64_t& result) >+inline Result WARN_UNUSED_RETURN decodeInt64(const uint8_t* bytes, size_t length, size_t& offset, int64_t& result) > { > return decodeInt<int64_t>(bytes, length, offset, result); > } >diff --git a/Source/WTF/wtf/StreamingError.h b/Source/WTF/wtf/StreamingError.h >new file mode 100644 >index 0000000000000000000000000000000000000000..62e42d6ea1625441bfdd12308f56db2742fce190 >--- /dev/null >+++ b/Source/WTF/wtf/StreamingError.h >@@ -0,0 +1,34 @@ >+/* >+ * Copyright (C) 2018 Yusuke Suzuki <yusukesuzuki@slowstart.org>. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+namespace WTF { >+ >+enum class StreamingError : uint8_t { Fatal, Recoverable }; >+ >+} // WTF >+ >+using WTF::StreamingError; >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 16a144fa6d071bfcafff4a330f4c1e0e3260d238..20dc90d667dafd7248c7ab05ce8f58312ae241fd 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,17 @@ >+2018-08-21 Yusuke Suzuki <yusukesuzuki@slowstart.org> >+ >+ LEBDecoder and Wasm::Parser should be tolerant for not enough data >+ https://bugs.webkit.org/show_bug.cgi?id=188788 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * TestWebKitAPI/Tests/WTF/LEBDecoder.cpp: >+ (TestWebKitAPI::testUInt32LEBDecode): >+ (TestWebKitAPI::TEST): >+ (TestWebKitAPI::testUInt64LEBDecode): >+ (TestWebKitAPI::testInt32LEBDecode): >+ (TestWebKitAPI::testInt64LEBDecode): >+ > 2018-08-20 Jonathan Bedard <jbedard@apple.com> > > WebKitTestRunner: Add watchOS entitlements >diff --git a/Tools/TestWebKitAPI/Tests/WTF/LEBDecoder.cpp b/Tools/TestWebKitAPI/Tests/WTF/LEBDecoder.cpp >index 2141080c436cb363e78429e5a6127b45db6636f8..d8bb899489ff19ec82dd96fc8dd5ee45c8719cf7 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/LEBDecoder.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/LEBDecoder.cpp >@@ -26,17 +26,18 @@ > #include "config.h" > > #include <wtf/LEBDecoder.h> >+#include <wtf/StreamingError.h> > #include <wtf/Vector.h> > > namespace TestWebKitAPI { > >-static void testUInt32LEBDecode(std::initializer_list<uint8_t> data, size_t startOffset, bool expectedStatus, uint32_t expectedResult, size_t expectedOffset) >+static void testUInt32LEBDecode(std::initializer_list<uint8_t> data, size_t startOffset, WTF::LEBDecoder::Result expectedStatus, uint32_t expectedResult, size_t expectedOffset) > { > Vector<uint8_t> vector(data); > uint32_t result; >- bool status = WTF::LEBDecoder::decodeUInt32(vector.data(), vector.size(), startOffset, result); >- EXPECT_EQ(expectedStatus, status); >- if (expectedStatus) { >+ auto status = WTF::LEBDecoder::decodeUInt32(vector.data(), vector.size(), startOffset, result); >+ EXPECT_TRUE(expectedStatus == status); >+ if (!!expectedStatus) { > EXPECT_EQ(expectedResult, result); > EXPECT_EQ(expectedOffset, startOffset); > } >@@ -45,45 +46,48 @@ static void testUInt32LEBDecode(std::initializer_list<uint8_t> data, size_t star > TEST(WTF, LEBDecoderUInt32) > { > // Simple tests that use all the bits in the array >- testUInt32LEBDecode({ 0x07 }, 0, true, 0x7lu, 1lu); >- testUInt32LEBDecode({ 0x77 }, 0, true, 0x77lu, 1lu); >- testUInt32LEBDecode({ 0x80, 0x07 }, 0, true, 0x380lu, 2lu); >- testUInt32LEBDecode({ 0x89, 0x12 }, 0, true, 0x909lu, 2lu); >- testUInt32LEBDecode({ 0xf3, 0x85, 0x02 }, 0, true, 0x82f3lu, 3lu); >- testUInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74 }, 0, true, 0xe9fc2f3lu, 4lu); >- testUInt32LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }, 0, true, 0xfe9fc2f3lu, 5lu); >+ testUInt32LEBDecode({ 0x07 }, 0, { }, 0x7lu, 1lu); >+ testUInt32LEBDecode({ 0x77 }, 0, { }, 0x77lu, 1lu); >+ testUInt32LEBDecode({ 0x80, 0x07 }, 0, { }, 0x380lu, 2lu); >+ testUInt32LEBDecode({ 0x89, 0x12 }, 0, { }, 0x909lu, 2lu); >+ testUInt32LEBDecode({ 0xf3, 0x85, 0x02 }, 0, { }, 0x82f3lu, 3lu); >+ testUInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74 }, 0, { }, 0xe9fc2f3lu, 4lu); >+ testUInt32LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }, 0, { }, 0xfe9fc2f3lu, 5lu); > // Test with extra trailing numbers >- testUInt32LEBDecode({ 0x07, 0x80 }, 0, true, 0x7lu, 1lu); >- testUInt32LEBDecode({ 0x07, 0x75 }, 0, true, 0x7lu, 1lu); >- testUInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x43 }, 0, true, 0xe9fc2f3lu, 4lu); >- testUInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x80 }, 0, true, 0xe9fc2f3lu, 4lu); >+ testUInt32LEBDecode({ 0x07, 0x80 }, 0, { }, 0x7lu, 1lu); >+ testUInt32LEBDecode({ 0x07, 0x75 }, 0, { }, 0x7lu, 1lu); >+ testUInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x43 }, 0, { }, 0xe9fc2f3lu, 4lu); >+ testUInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x80 }, 0, { }, 0xe9fc2f3lu, 4lu); > // Test with preceeding numbers >- testUInt32LEBDecode({ 0xf3, 0x07 }, 1, true, 0x7lu, 2lu); >- testUInt32LEBDecode({ 0x03, 0x07 }, 1, true, 0x7lu, 2lu); >- testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }, 5, true, 0x77lu, 6lu); >- testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }, 5, true, 0x77lu, 6ul); >- testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }, 3, true, 0x82f3lu, 6lu); >+ testUInt32LEBDecode({ 0xf3, 0x07 }, 1, { }, 0x7lu, 2lu); >+ testUInt32LEBDecode({ 0x03, 0x07 }, 1, { }, 0x7lu, 2lu); >+ testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }, 5, { }, 0x77lu, 6lu); >+ testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }, 5, { }, 0x77lu, 6ul); >+ testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }, 3, { }, 0x82f3lu, 6lu); > // Test in the middle >- testUInt32LEBDecode({ 0xf3, 0x07, 0x89 }, 1, true, 0x7lu, 2lu); >- testUInt32LEBDecode({ 0x03, 0x07, 0x23 }, 1, true, 0x7lu, 2lu); >- testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }, 5, true, 0x77lu, 6lu); >- testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }, 5, true, 0x77lu, 6lu); >- testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }, 3, true, 0x82f3lu, 6lu); >+ testUInt32LEBDecode({ 0xf3, 0x07, 0x89 }, 1, { }, 0x7lu, 2lu); >+ testUInt32LEBDecode({ 0x03, 0x07, 0x23 }, 1, { }, 0x7lu, 2lu); >+ testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }, 5, { }, 0x77lu, 6lu); >+ testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }, 5, { }, 0x77lu, 6lu); >+ testUInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }, 3, { }, 0x82f3lu, 6lu); >+ // Test decode too short >+ testUInt32LEBDecode({ 0x81 }, 0, makeUnexpected(StreamingError::Recoverable), 0x0lu, 0lu); >+ testUInt32LEBDecode({ 0x80, 0x81 }, 0, makeUnexpected(StreamingError::Recoverable), 0x0lu, 0lu); > // Test decode too long >- testUInt32LEBDecode({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, false, 0x0lu, 0lu); >- testUInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 1, false, 0x0lu, 0lu); >- testUInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 0, false, 0x0lu, 0lu); >+ testUInt32LEBDecode({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); >+ testUInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 1, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); >+ testUInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 0, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); > // Test decode off end of array >- testUInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 2, false, 0x0lu, 0lu); >+ testUInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 2, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); > } > >-static void testUInt64LEBDecode(std::initializer_list<uint8_t> data, size_t startOffset, bool expectedStatus, uint64_t expectedResult, size_t expectedOffset) >+static void testUInt64LEBDecode(std::initializer_list<uint8_t> data, size_t startOffset, WTF::LEBDecoder::Result expectedStatus, uint64_t expectedResult, size_t expectedOffset) > { > Vector<uint8_t> vector(data); > uint64_t result; >- bool status = WTF::LEBDecoder::decodeUInt64(vector.data(), vector.size(), startOffset, result); >- EXPECT_EQ(expectedStatus, status); >- if (expectedStatus) { >+ auto status = WTF::LEBDecoder::decodeUInt64(vector.data(), vector.size(), startOffset, result); >+ EXPECT_TRUE(expectedStatus == status); >+ if (!!expectedStatus) { > EXPECT_EQ(expectedResult, result); > EXPECT_EQ(expectedOffset, startOffset); > } >@@ -92,58 +96,60 @@ static void testUInt64LEBDecode(std::initializer_list<uint8_t> data, size_t star > TEST(WTF, LEBDecoderUInt64) > { > // Simple tests that use all the bits in the array >- testUInt64LEBDecode({ 0x07 }, 0, true, 0x7lu, 1lu); >- testUInt64LEBDecode({ 0x77 }, 0, true, 0x77lu, 1lu); >- testUInt64LEBDecode({ 0x80, 0x07 }, 0, true, 0x380lu, 2lu); >- testUInt64LEBDecode({ 0x89, 0x12 }, 0, true, 0x909lu, 2lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0x02 }, 0, true, 0x82f3lu, 3lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74 }, 0, true, 0xe9fc2f3lu, 4lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }, 0, true, 0x7fe9fc2f3lu, 5lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0x4b }, 0, true, 0x25ffe9fc2f3lu, 6lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0x3a }, 0, true, 0xea5ffe9fc2f3lu, 7lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x0f }, 0, true, 0x1eea5ffe9fc2f3lu, 8lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69 }, 0, true, 0x691eea5ffe9fc2f3lu, 9lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0xe9, 0x01 }, 0, true, 0xe91eea5ffe9fc2f3lu, 10lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0xe9, 0x70 }, 0, true, 0x691eea5ffe9fc2f3lu, 10lu); >+ testUInt64LEBDecode({ 0x07 }, 0, { }, 0x7lu, 1lu); >+ testUInt64LEBDecode({ 0x77 }, 0, { }, 0x77lu, 1lu); >+ testUInt64LEBDecode({ 0x80, 0x07 }, 0, { }, 0x380lu, 2lu); >+ testUInt64LEBDecode({ 0x89, 0x12 }, 0, { }, 0x909lu, 2lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0x02 }, 0, { }, 0x82f3lu, 3lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74 }, 0, { }, 0xe9fc2f3lu, 4lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }, 0, { }, 0x7fe9fc2f3lu, 5lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0x4b }, 0, { }, 0x25ffe9fc2f3lu, 6lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0x3a }, 0, { }, 0xea5ffe9fc2f3lu, 7lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x0f }, 0, { }, 0x1eea5ffe9fc2f3lu, 8lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69 }, 0, { }, 0x691eea5ffe9fc2f3lu, 9lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0xe9, 0x01 }, 0, { }, 0xe91eea5ffe9fc2f3lu, 10lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0xe9, 0x70 }, 0, { }, 0x691eea5ffe9fc2f3lu, 10lu); > // Test with extra trailing numbers >- testUInt64LEBDecode({ 0x07, 0x80 }, 0, true, 0x7lu, 1lu); >- testUInt64LEBDecode({ 0x07, 0x75 }, 0, true, 0x7lu, 1lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x43 }, 0, true, 0xe9fc2f3lu, 4lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x80 }, 0, true, 0xe9fc2f3lu, 4lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69, 0x45 }, 0, true, 0x691eea5ffe9fc2f3lu, 9lu); >+ testUInt64LEBDecode({ 0x07, 0x80 }, 0, { }, 0x7lu, 1lu); >+ testUInt64LEBDecode({ 0x07, 0x75 }, 0, { }, 0x7lu, 1lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x43 }, 0, { }, 0xe9fc2f3lu, 4lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x80 }, 0, { }, 0xe9fc2f3lu, 4lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69, 0x45 }, 0, { }, 0x691eea5ffe9fc2f3lu, 9lu); > // Test with preceeding numbers >- testUInt64LEBDecode({ 0xf3, 0x07 }, 1, true, 0x7lu, 2lu); >- testUInt64LEBDecode({ 0x03, 0x07 }, 1, true, 0x7lu, 2lu); >- testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }, 5, true, 0x77lu, 6lu); >- testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }, 5, true, 0x77lu, 6ul); >- testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }, 3, true, 0x82f3lu, 6lu); >- testUInt64LEBDecode({ 0x92, 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69 }, 1, true, 0x691eea5ffe9fc2f3lu, 10lu); >+ testUInt64LEBDecode({ 0xf3, 0x07 }, 1, { }, 0x7lu, 2lu); >+ testUInt64LEBDecode({ 0x03, 0x07 }, 1, { }, 0x7lu, 2lu); >+ testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }, 5, { }, 0x77lu, 6lu); >+ testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }, 5, { }, 0x77lu, 6ul); >+ testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }, 3, { }, 0x82f3lu, 6lu); >+ testUInt64LEBDecode({ 0x92, 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69 }, 1, { }, 0x691eea5ffe9fc2f3lu, 10lu); > // Test in the middle >- testUInt64LEBDecode({ 0xf3, 0x07, 0x89 }, 1, true, 0x7lu, 2lu); >- testUInt64LEBDecode({ 0x03, 0x07, 0x23 }, 1, true, 0x7lu, 2lu); >- testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }, 5, true, 0x77lu, 6lu); >- testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }, 5, true, 0x77lu, 6lu); >- testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }, 3, true, 0x82f3lu, 6lu); >- testUInt64LEBDecode({ 0x92, 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69, 0x85, 0x75 }, 1, true, 0x691eea5ffe9fc2f3lu, 10lu); >- testUInt64LEBDecode({ 0x92, 0x65, 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69, 0x85, 0x75 }, 2, true, 0x691eea5ffe9fc2f3lu, 11lu); >+ testUInt64LEBDecode({ 0xf3, 0x07, 0x89 }, 1, { }, 0x7lu, 2lu); >+ testUInt64LEBDecode({ 0x03, 0x07, 0x23 }, 1, { }, 0x7lu, 2lu); >+ testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }, 5, { }, 0x77lu, 6lu); >+ testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }, 5, { }, 0x77lu, 6lu); >+ testUInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }, 3, { }, 0x82f3lu, 6lu); >+ testUInt64LEBDecode({ 0x92, 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69, 0x85, 0x75 }, 1, { }, 0x691eea5ffe9fc2f3lu, 10lu); >+ testUInt64LEBDecode({ 0x92, 0x65, 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0x69, 0x85, 0x75 }, 2, { }, 0x691eea5ffe9fc2f3lu, 11lu); >+ // Test decode too short >+ testUInt64LEBDecode({ 0x80 }, 0, makeUnexpected(StreamingError::Recoverable), 0x0lu, 0lu); >+ testUInt64LEBDecode({ 0x80, 0x81 }, 0, makeUnexpected(StreamingError::Recoverable), 0x0lu, 0lu); > // Test decode too long >- testUInt64LEBDecode({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, false, 0x0lu, 0lu); >- testUInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xa3, 0x9f, 0xd2, 0xef, 0x8a, 0x4e }, 1, false, 0x0lu, 0lu); >- testUInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff, 0xef, 0xd8, 0xee, 0xaa, 0xbb }, 0, false, 0x0lu, 0lu); >- testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0xa9, 0xa8, 0x05 }, 0, false, 0x0lu, 0lu); >+ testUInt64LEBDecode({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); >+ testUInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xa3, 0x9f, 0xd2, 0xef, 0x8a, 0x4e }, 1, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); >+ testUInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff, 0xef, 0xd8, 0xee, 0xaa, 0xbb }, 0, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); >+ testUInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0xa9, 0xa8, 0x05 }, 0, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); > // Test decode off end of array >- testUInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 2, false, 0x0lu, 0lu); >- testUInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 2, false, 0x0lu, 0lu); >- testUInt64LEBDecode({ 0x92, 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f }, 1, false, 0x0lu, 0lu); >+ testUInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 2, makeUnexpected(StreamingError::Recoverable), 0x0lu, 0lu); >+ testUInt64LEBDecode({ 0x92, 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f }, 1, makeUnexpected(StreamingError::Recoverable), 0x0lu, 0lu); > } > >-static void testInt32LEBDecode(std::initializer_list<uint8_t> data, size_t startOffset, bool expectedStatus, int32_t expectedResult, size_t expectedOffset) >+static void testInt32LEBDecode(std::initializer_list<uint8_t> data, size_t startOffset, WTF::LEBDecoder::Result expectedStatus, int32_t expectedResult, size_t expectedOffset) > { > Vector<uint8_t> vector(data); > int32_t result; >- bool status = WTF::LEBDecoder::decodeInt32(vector.data(), vector.size(), startOffset, result); >- EXPECT_EQ(expectedStatus, status); >- if (expectedStatus) { >+ auto status = WTF::LEBDecoder::decodeInt32(vector.data(), vector.size(), startOffset, result); >+ EXPECT_TRUE(expectedStatus == status); >+ if (!!expectedStatus) { > EXPECT_EQ(expectedResult, result); > EXPECT_EQ(expectedOffset, startOffset); > } >@@ -152,45 +158,48 @@ static void testInt32LEBDecode(std::initializer_list<uint8_t> data, size_t start > TEST(WTF, LEBDecoderInt32) > { > // Simple tests that use all the bits in the array >- testInt32LEBDecode({ 0x07 }, 0, true, 0x7, 1lu); >- testInt32LEBDecode({ 0x77 }, 0, true, -0x9, 1lu); >- testInt32LEBDecode({ 0x80, 0x07 }, 0, true, 0x380, 2lu); >- testInt32LEBDecode({ 0x89, 0x12 }, 0, true, 0x909, 2lu); >- testInt32LEBDecode({ 0xf3, 0x85, 0x02 }, 0, true, 0x82f3, 3lu); >- testInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74 }, 0, true, 0xfe9fc2f3, 4lu); >- testInt32LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }, 0, true, 0xfe9fc2f3, 5lu); >+ testInt32LEBDecode({ 0x07 }, 0, { }, 0x7, 1lu); >+ testInt32LEBDecode({ 0x77 }, 0, { }, -0x9, 1lu); >+ testInt32LEBDecode({ 0x80, 0x07 }, 0, { }, 0x380, 2lu); >+ testInt32LEBDecode({ 0x89, 0x12 }, 0, { }, 0x909, 2lu); >+ testInt32LEBDecode({ 0xf3, 0x85, 0x02 }, 0, { }, 0x82f3, 3lu); >+ testInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74 }, 0, { }, 0xfe9fc2f3, 4lu); >+ testInt32LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }, 0, { }, 0xfe9fc2f3, 5lu); > // Test with extra trailing numbers >- testInt32LEBDecode({ 0x07, 0x80 }, 0, true, 0x7, 1lu); >- testInt32LEBDecode({ 0x07, 0x75 }, 0, true, 0x7, 1lu); >- testInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x43 }, 0, true, 0xfe9fc2f3, 4lu); >- testInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x80 }, 0, true, 0xfe9fc2f3, 4lu); >+ testInt32LEBDecode({ 0x07, 0x80 }, 0, { }, 0x7, 1lu); >+ testInt32LEBDecode({ 0x07, 0x75 }, 0, { }, 0x7, 1lu); >+ testInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x43 }, 0, { }, 0xfe9fc2f3, 4lu); >+ testInt32LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x80 }, 0, { }, 0xfe9fc2f3, 4lu); > // Test with preceeding numbers >- testInt32LEBDecode({ 0xf3, 0x07 }, 1, true, 0x7, 2lu); >- testInt32LEBDecode({ 0x03, 0x07 }, 1, true, 0x7, 2lu); >- testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }, 5, true, -0x9, 6lu); >- testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }, 5, true, -0x9, 6lu); >- testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }, 3, true, 0x82f3, 6lu); >+ testInt32LEBDecode({ 0xf3, 0x07 }, 1, { }, 0x7, 2lu); >+ testInt32LEBDecode({ 0x03, 0x07 }, 1, { }, 0x7, 2lu); >+ testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }, 5, { }, -0x9, 6lu); >+ testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }, 5, { }, -0x9, 6lu); >+ testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }, 3, { }, 0x82f3, 6lu); > // Test in the middle >- testInt32LEBDecode({ 0xf3, 0x07, 0x89 }, 1, true, 0x7, 2lu); >- testInt32LEBDecode({ 0x03, 0x07, 0x23 }, 1, true, 0x7, 2lu); >- testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }, 5, true, -0x9, 6lu); >- testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }, 5, true, -0x9, 6lu); >- testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }, 3, true, 0x82f3, 6lu); >+ testInt32LEBDecode({ 0xf3, 0x07, 0x89 }, 1, { }, 0x7, 2lu); >+ testInt32LEBDecode({ 0x03, 0x07, 0x23 }, 1, { }, 0x7, 2lu); >+ testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }, 5, { }, -0x9, 6lu); >+ testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }, 5, { }, -0x9, 6lu); >+ testInt32LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }, 3, { }, 0x82f3, 6lu); >+ // Test decode too short >+ testInt32LEBDecode({ 0x80 }, 0, makeUnexpected(StreamingError::Recoverable), 0x0, 0lu); >+ testInt32LEBDecode({ 0x80, 0x81 }, 0, makeUnexpected(StreamingError::Recoverable), 0x0, 0lu); > // Test decode too long >- testInt32LEBDecode({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, false, 0x0, 0lu); >- testInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 1, false, 0x0, 0lu); >- testInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 0, false, 0x0, 0lu); >+ testInt32LEBDecode({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, makeUnexpected(StreamingError::Fatal), 0x0, 0lu); >+ testInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 1, makeUnexpected(StreamingError::Fatal), 0x0, 0lu); >+ testInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 0, makeUnexpected(StreamingError::Fatal), 0x0, 0lu); > // Test decode off end of array >- testInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 2, false, 0x0, 0lu); >+ testInt32LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 2, makeUnexpected(StreamingError::Fatal), 0x0, 0lu); > } > >-static void testInt64LEBDecode(std::initializer_list<uint8_t> data, size_t startOffset, bool expectedStatus, int64_t expectedResult, size_t expectedOffset) >+static void testInt64LEBDecode(std::initializer_list<uint8_t> data, size_t startOffset, WTF::LEBDecoder::Result expectedStatus, int64_t expectedResult, size_t expectedOffset) > { > Vector<uint8_t> vector(data); > int64_t result; >- bool status = WTF::LEBDecoder::decodeInt64(vector.data(), vector.size(), startOffset, result); >- EXPECT_EQ(expectedStatus, status); >- if (expectedStatus) { >+ auto status = WTF::LEBDecoder::decodeInt64(vector.data(), vector.size(), startOffset, result); >+ EXPECT_TRUE(expectedStatus == status); >+ if (!!expectedStatus) { > EXPECT_EQ(expectedResult, result); > EXPECT_EQ(expectedOffset, startOffset); > } >@@ -199,42 +208,50 @@ static void testInt64LEBDecode(std::initializer_list<uint8_t> data, size_t start > TEST(WTF, LEBDecoderInt64) > { > // Simple tests that use all the bits in the array >- testInt64LEBDecode({ 0x07 }, 0, true, 0x7, 1lu); >- testInt64LEBDecode({ 0x77 }, 0, true, -0x9, 1lu); >- testInt64LEBDecode({ 0x80, 0x07 }, 0, true, 0x380, 2lu); >- testInt64LEBDecode({ 0x89, 0x12 }, 0, true, 0x909, 2lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0x02 }, 0, true, 0x82f3, 3lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74 }, 0, true, 0xfffffffffe9fc2f3, 4lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }, 0, true, 0xfffffffffe9fc2f3, 5lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x3f }, 0, true, 0x3fe9fc2f3, 5lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x1a }, 0, true, 0xd0fe9fc2f3, 6lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x9a, 0x80, 0x2a }, 0, true, 0x5400d0fe9fc2f3, 8lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x9a, 0x80, 0xaa, 0x41 }, 0, true, 0xc15400d0fe9fc2f3, 9lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x9a, 0x80, 0xaa, 0xc1, 0x01 }, 0, true, 0xc15400d0fe9fc2f3, 10lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x9a, 0x80, 0xaa, 0xc1, 0x62 }, 0, true, 0x415400d0fe9fc2f3, 10lu); >+ testInt64LEBDecode({ 0x07 }, 0, { }, 0x7, 1lu); >+ testInt64LEBDecode({ 0x77 }, 0, { }, -0x9, 1lu); >+ testInt64LEBDecode({ 0x80, 0x07 }, 0, { }, 0x380, 2lu); >+ testInt64LEBDecode({ 0x89, 0x12 }, 0, { }, 0x909, 2lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0x02 }, 0, { }, 0x82f3, 3lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74 }, 0, { }, 0xfffffffffe9fc2f3, 4lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }, 0, { }, 0xfffffffffe9fc2f3, 5lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x3f }, 0, { }, 0x3fe9fc2f3, 5lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x1a }, 0, { }, 0xd0fe9fc2f3, 6lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x9a, 0x80, 0x2a }, 0, { }, 0x5400d0fe9fc2f3, 8lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x9a, 0x80, 0xaa, 0x41 }, 0, { }, 0xc15400d0fe9fc2f3, 9lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x9a, 0x80, 0xaa, 0xc1, 0x01 }, 0, { }, 0xc15400d0fe9fc2f3, 10lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0x8f, 0x9a, 0x80, 0xaa, 0xc1, 0x62 }, 0, { }, 0x415400d0fe9fc2f3, 10lu); > // Test with extra trailing numbers >- testInt64LEBDecode({ 0x07, 0x80 }, 0, true, 0x7, 1lu); >- testInt64LEBDecode({ 0x07, 0x75 }, 0, true, 0x7, 1lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x43 }, 0, true, 0xfffffffffe9fc2f3, 4lu); >- testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x80 }, 0, true, 0xfffffffffe9fc2f3, 4lu); >+ testInt64LEBDecode({ 0x07, 0x80 }, 0, { }, 0x7, 1lu); >+ testInt64LEBDecode({ 0x07, 0x75 }, 0, { }, 0x7, 1lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x43 }, 0, { }, 0xfffffffffe9fc2f3, 4lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0x74, 0x80 }, 0, { }, 0xfffffffffe9fc2f3, 4lu); > // Test with preceeding numbers >- testInt64LEBDecode({ 0xf3, 0x07 }, 1, true, 0x7, 2lu); >- testInt64LEBDecode({ 0x03, 0x07 }, 1, true, 0x7, 2lu); >- testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }, 5, true, -0x9, 6lu); >- testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }, 5, true, -0x9, 6lu); >- testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }, 3, true, 0x82f3, 6lu); >+ testInt64LEBDecode({ 0xf3, 0x07 }, 1, { }, 0x7, 2lu); >+ testInt64LEBDecode({ 0x03, 0x07 }, 1, { }, 0x7, 2lu); >+ testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }, 5, { }, -0x9, 6lu); >+ testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }, 5, { }, -0x9, 6lu); >+ testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }, 3, { }, 0x82f3, 6lu); > // Test in the middle >- testInt64LEBDecode({ 0xf3, 0x07, 0x89 }, 1, true, 0x7, 2lu); >- testInt64LEBDecode({ 0x03, 0x07, 0x23 }, 1, true, 0x7, 2lu); >- testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }, 5, true, -0x9, 6lu); >- testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }, 5, true, -0x9, 6lu); >- testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }, 3, true, 0x82f3, 6lu); >+ testInt64LEBDecode({ 0xf3, 0x07, 0x89 }, 1, { }, 0x7, 2lu); >+ testInt64LEBDecode({ 0x03, 0x07, 0x23 }, 1, { }, 0x7, 2lu); >+ testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }, 5, { }, -0x9, 6lu); >+ testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }, 5, { }, -0x9, 6lu); >+ testInt64LEBDecode({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }, 3, { }, 0x82f3, 6lu); >+ // Test decode too short >+ testInt64LEBDecode({ 0x80 }, 0, makeUnexpected(StreamingError::Recoverable), 0x0, 0lu); >+ testInt64LEBDecode({ 0x80, 0x81 }, 0, makeUnexpected(StreamingError::Recoverable), 0x0, 0lu); >+ testInt64LEBDecode({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, makeUnexpected(StreamingError::Recoverable), 0x0, 0lu); >+ testInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 1, makeUnexpected(StreamingError::Recoverable), 0x0, 0lu); >+ testInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 0, makeUnexpected(StreamingError::Recoverable), 0x0, 0lu); > // Test decode too long >- testInt64LEBDecode({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, false, 0x0, 0lu); >- testInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 1, false, 0x0, 0lu); >- testInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 0, false, 0x0, 0lu); >+ testInt64LEBDecode({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); >+ testInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xa3, 0x9f, 0xd2, 0xef, 0x8a, 0x4e }, 1, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); >+ testInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff, 0xef, 0xd8, 0xee, 0xaa, 0xbb }, 0, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); >+ testInt64LEBDecode({ 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f, 0xa9, 0xa8, 0x05 }, 0, makeUnexpected(StreamingError::Fatal), 0x0lu, 0lu); > // Test decode off end of array >- testInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 2, false, 0x0, 0lu); >+ testInt64LEBDecode({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff }, 2, makeUnexpected(StreamingError::Recoverable), 0x0lu, 0lu); >+ testInt64LEBDecode({ 0x92, 0xf3, 0x85, 0xff, 0xf4, 0xff, 0xcb, 0xba, 0x8f }, 1, makeUnexpected(StreamingError::Recoverable), 0x0lu, 0lu); > } > >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188788
: 347632