From 54a894318e16fd7e093f1eb942a0866b7a3923ab Mon Sep 17 00:00:00 2001 From: Alexey Toptygin Date: Mon, 24 Apr 2017 09:01:28 -0700 Subject: [PATCH] Make "String length exceeded" fatal consistent and correct. Summary: Merge different ways of producing a "String length exceeded" fatal into one helper, and make the error message reflect the actual limit. Reviewed By: markw65 Differential Revision: D4893949 fbshipit-source-id: 13b7018976de61c1d85d0152b9de4fa69c05241a --- hphp/runtime/base/string-data.cpp | 24 +++++++++------------- hphp/runtime/base/string-data.h | 9 ++++++-- hphp/runtime/base/string-util.cpp | 3 +-- hphp/runtime/ext/string/ext_string.cpp | 3 +-- .../ext_string/chunk_split_overflow.php.expectf | 3 +-- hphp/test/slow/string/escapeshellarg.php.expectf | 2 +- hphp/test/slow/string/quoted_printable.php.expectf | 2 +- hphp/test/slow/string/urlencode.php.expectf | 2 +- .../slow/string_length_overflow/fread.php.expectf | 2 +- .../string_length_overflow/implode.php.expectf | 3 +-- .../nzuncompress.php.expectf | 2 +- .../slow/string_length_overflow/thrift.php.expectf | 2 +- .../string_length_overflow/utf8_encode.php.expectf | 2 +- 13 files changed, 28 insertions(+), 31 deletions(-) diff --git a/hphp/runtime/base/string-data.cpp b/hphp/runtime/base/string-data.cpp index 878af85ef92..7272a8ae952 100644 --- a/hphp/runtime/base/string-data.cpp +++ b/hphp/runtime/base/string-data.cpp @@ -40,18 +40,14 @@ namespace HPHP { ////////////////////////////////////////////////////////////////////// -namespace { - -NEVER_INLINE void throw_string_too_large(size_t len) { - raise_error("String length exceeded 2^31-2: %zu", len); -} - +NEVER_INLINE void raiseStringLengthExceededError(size_t len) { + raise_error("String length exceeded: %zu > %u", len, StringData::MaxSize); } // Allocate, initialize `m_data' and HeapObject, but not `m_lenAndHash'. ALWAYS_INLINE StringData* allocFlat(size_t len) { if (UNLIKELY(len > StringData::MaxSize)) { - throw_string_too_large(len); + raiseStringLengthExceededError(len); } auto const sizeClass = MemoryManager::size2Index(len + kStringOverhead); StringData* sd; @@ -95,7 +91,7 @@ ALWAYS_INLINE static bool UncountedStringOnHugePage() { template ALWAYS_INLINE StringData* StringData::MakeShared(folly::StringPiece sl) { if (UNLIKELY(sl.size() > StringData::MaxSize)) { - throw_string_too_large(sl.size()); + raiseStringLengthExceededError(sl.size()); } auto const allocSize = sl.size() + kStringOverhead; @@ -234,7 +230,7 @@ StringData* StringData::Make(folly::StringPiece sl, CopyStringMode) { StringData* StringData::Make(const char* data, size_t len, CopyStringMode) { if (UNLIKELY(len > StringData::MaxSize)) { - throw_string_too_large(len); + raiseStringLengthExceededError(len); } return Make(folly::StringPiece(data, len), CopyString); @@ -258,7 +254,7 @@ StringData* StringData::Make() { StringData* StringData::Make(char* data, size_t len, AttachStringMode) { if (UNLIKELY(len > StringData::MaxSize)) { - throw_string_too_large(len); + raiseStringLengthExceededError(len); } auto const sd = Make(folly::StringPiece(data, len), CopyString); free(data); @@ -422,7 +418,7 @@ StringData* StringData::append(folly::StringPiece range) { auto const newLen = size_t(m_len) + size_t(len); if (UNLIKELY(newLen > MaxSize)) { - throw_string_too_large(newLen); + raiseStringLengthExceededError(newLen); } /* @@ -449,7 +445,7 @@ StringData* StringData::append(folly::StringPiece r1, folly::StringPiece r2) { if (len == 0) return this; if (UNLIKELY(size_t(m_len) + size_t(len) > MaxSize)) { - throw_string_too_large(size_t(len) + size_t(m_len)); + raiseStringLengthExceededError(size_t(len) + size_t(m_len)); } auto const newLen = m_len + len; @@ -489,7 +485,7 @@ StringData* StringData::append(folly::StringPiece r1, if (len == 0) return this; if (UNLIKELY(size_t(m_len) + size_t(len) > MaxSize)) { - throw_string_too_large(size_t(len) + size_t(m_len)); + raiseStringLengthExceededError(size_t(len) + size_t(m_len)); } auto const newLen = m_len + len; @@ -699,7 +695,7 @@ void StringData::incrementHelper() { if (carry) { if (UNLIKELY(len + 1 > MaxSize)) { - throw_string_too_large(len + 1); + raiseStringLengthExceededError(len + 1); } assert(len + 1 <= capacity()); diff --git a/hphp/runtime/base/string-data.h b/hphp/runtime/base/string-data.h index d269b920182..9c3b88d85c8 100644 --- a/hphp/runtime/base/string-data.h +++ b/hphp/runtime/base/string-data.h @@ -526,8 +526,8 @@ static_assert(StringData::MaxSize + kStringOverhead == kSizeIndex2Size[103], "max allocation size is a valid size class"); /* - * A reasonable length to reserve for small strings. This is the - * default reserve size for StringData::Make(), also. + * A reasonable length to reserve for small strings. This is also the + * default reserve size for StringData::Make(). */ constexpr uint32_t SmallStringReserve = 64 - kStringOverhead; @@ -541,6 +541,11 @@ alignas(64) constexpr uint32_t kSizeIndex2StringCapacity[] = { }; /* + * Call this if we tried to make a string longer than StringData::MaxSize + */ +void raiseStringLengthExceededError(size_t len); + +/* * DecRef a string s, calling release if its reference count goes to * zero. */ diff --git a/hphp/runtime/base/string-util.cpp b/hphp/runtime/base/string-util.cpp index 0f2afff4818..82cc193a28a 100644 --- a/hphp/runtime/base/string-util.cpp +++ b/hphp/runtime/base/string-util.cpp @@ -475,8 +475,7 @@ size_t safe_address(size_t nmemb, size_t size, size_t offset) { uint64_t result = (uint64_t) nmemb * (uint64_t) size + (uint64_t) offset; if (UNLIKELY(result > StringData::MaxSize)) { - throw - FatalErrorException(0, "String length exceeded 2^31-2: %" PRIu64, result); + raiseStringLengthExceededError(result); } return result; } diff --git a/hphp/runtime/ext/string/ext_string.cpp b/hphp/runtime/ext/string/ext_string.cpp index 66bbd419804..a2c60ddabb1 100644 --- a/hphp/runtime/ext/string/ext_string.cpp +++ b/hphp/runtime/ext/string/ext_string.cpp @@ -911,8 +911,7 @@ String HHVM_FUNCTION(str_repeat, auto size = multiplier * size_t(input.size()); if (multiplier >= StringData::MaxSize || size > StringData::MaxSize) { - throw - FatalErrorException(0, "String length exceeded 2^31-2: %" PRIu64, size); + raiseStringLengthExceededError(size); } StringBuffer ret(input.size() * multiplier); diff --git a/hphp/test/slow/ext_string/chunk_split_overflow.php.expectf b/hphp/test/slow/ext_string/chunk_split_overflow.php.expectf index 17c953f9163..c515dc11f52 100644 --- a/hphp/test/slow/ext_string/chunk_split_overflow.php.expectf +++ b/hphp/test/slow/ext_string/chunk_split_overflow.php.expectf @@ -1,2 +1 @@ - -Fatal error: String length exceeded 2^31-2: 4000004000000 in %s on line 3 +Fatal error: String length exceeded: %d > %d in %s on line %d diff --git a/hphp/test/slow/string/escapeshellarg.php.expectf b/hphp/test/slow/string/escapeshellarg.php.expectf index d9b32fcaadd..c515dc11f52 100644 --- a/hphp/test/slow/string/escapeshellarg.php.expectf +++ b/hphp/test/slow/string/escapeshellarg.php.expectf @@ -1 +1 @@ -Fatal error: String length exceeded 2^31-2: %d in %s on line 2 +Fatal error: String length exceeded: %d > %d in %s on line %d diff --git a/hphp/test/slow/string/quoted_printable.php.expectf b/hphp/test/slow/string/quoted_printable.php.expectf index 4c9e1a93f5f..c515dc11f52 100644 --- a/hphp/test/slow/string/quoted_printable.php.expectf +++ b/hphp/test/slow/string/quoted_printable.php.expectf @@ -1 +1 @@ -Fatal error: String length exceeded 2^31-2: %d in %s on line 3 +Fatal error: String length exceeded: %d > %d in %s on line %d diff --git a/hphp/test/slow/string/urlencode.php.expectf b/hphp/test/slow/string/urlencode.php.expectf index d9b32fcaadd..c515dc11f52 100644 --- a/hphp/test/slow/string/urlencode.php.expectf +++ b/hphp/test/slow/string/urlencode.php.expectf @@ -1 +1 @@ -Fatal error: String length exceeded 2^31-2: %d in %s on line 2 +Fatal error: String length exceeded: %d > %d in %s on line %d diff --git a/hphp/test/slow/string_length_overflow/fread.php.expectf b/hphp/test/slow/string_length_overflow/fread.php.expectf index 843e7f6e8d1..c515dc11f52 100644 --- a/hphp/test/slow/string_length_overflow/fread.php.expectf +++ b/hphp/test/slow/string_length_overflow/fread.php.expectf @@ -1 +1 @@ -Fatal error: String length exceeded %s +Fatal error: String length exceeded: %d > %d in %s on line %d diff --git a/hphp/test/slow/string_length_overflow/implode.php.expectf b/hphp/test/slow/string_length_overflow/implode.php.expectf index 484c51265ce..c515dc11f52 100644 --- a/hphp/test/slow/string_length_overflow/implode.php.expectf +++ b/hphp/test/slow/string_length_overflow/implode.php.expectf @@ -1,2 +1 @@ - -Fatal error: String length exceeded 2^31-2: 15008494201 in %s/test/slow/string_length_overflow/implode.php on line 5 +Fatal error: String length exceeded: %d > %d in %s on line %d diff --git a/hphp/test/slow/string_length_overflow/nzuncompress.php.expectf b/hphp/test/slow/string_length_overflow/nzuncompress.php.expectf index 843e7f6e8d1..c515dc11f52 100644 --- a/hphp/test/slow/string_length_overflow/nzuncompress.php.expectf +++ b/hphp/test/slow/string_length_overflow/nzuncompress.php.expectf @@ -1 +1 @@ -Fatal error: String length exceeded %s +Fatal error: String length exceeded: %d > %d in %s on line %d diff --git a/hphp/test/slow/string_length_overflow/thrift.php.expectf b/hphp/test/slow/string_length_overflow/thrift.php.expectf index 843e7f6e8d1..c515dc11f52 100644 --- a/hphp/test/slow/string_length_overflow/thrift.php.expectf +++ b/hphp/test/slow/string_length_overflow/thrift.php.expectf @@ -1 +1 @@ -Fatal error: String length exceeded %s +Fatal error: String length exceeded: %d > %d in %s on line %d diff --git a/hphp/test/slow/string_length_overflow/utf8_encode.php.expectf b/hphp/test/slow/string_length_overflow/utf8_encode.php.expectf index 843e7f6e8d1..c515dc11f52 100644 --- a/hphp/test/slow/string_length_overflow/utf8_encode.php.expectf +++ b/hphp/test/slow/string_length_overflow/utf8_encode.php.expectf @@ -1 +1 @@ -Fatal error: String length exceeded %s +Fatal error: String length exceeded: %d > %d in %s on line %d -- 2.11.4.GIT