@@ -26,6 +26,8 @@ extern "C" {
2626#define zend_string_release_ex (s, persistent ) zend_string_release((s))
2727#endif
2828
29+ #define SIMDJSON_DEPTH_CHECK_THRESHOLD 100000
30+
2931static inline simdjson::simdjson_result<simdjson::dom::element>
3032get_key_with_optional_prefix (simdjson::dom::element &doc, std::string_view json_pointer)
3133{
@@ -36,6 +38,25 @@ get_key_with_optional_prefix(simdjson::dom::element &doc, std::string_view json_
3638static simdjson::error_code
3739build_parsed_json_cust (simdjson::dom::parser& parser, simdjson::dom::element &doc, const char *buf, size_t len, bool realloc_if_needed,
3840 size_t depth = simdjson::DEFAULT_MAX_DEPTH) {
41+ if (UNEXPECTED (depth > SIMDJSON_DEPTH_CHECK_THRESHOLD) && depth > len && depth > parser.max_depth ()) {
42+ /*
43+ * Choose the depth in a way that both avoids frequent reallocations
44+ * and avoids excessive amounts of wasted memory beyond multiples of the largest string ever decoded.
45+ *
46+ * If the depth is already sufficient to parse a string of length `len`,
47+ * then use the parser's previous depth.
48+ *
49+ * Precondition: depth > len
50+ * Postcondition: depth <= original_depth && depth > len
51+ */
52+ if (len < SIMDJSON_DEPTH_CHECK_THRESHOLD) {
53+ depth = SIMDJSON_DEPTH_CHECK_THRESHOLD;
54+ } else if (depth > len * 2 ) {
55+ // In callers, simdjson_validate_depth ensures depth <= SIMDJSON_MAX_DEPTH (which is <= SIZE_MAX/8),
56+ // so len * 2 is even smaller than the previous depth and won't overflow.
57+ depth = len * 2 ;
58+ }
59+ }
3960 auto error = parser.allocate (len, depth);
4061
4162 if (error) {
0 commit comments