diff --git a/src/ripple/app/hook/impl/applyHook.cpp b/src/ripple/app/hook/impl/applyHook.cpp index 49450f6eb..cedd703b6 100644 --- a/src/ripple/app/hook/impl/applyHook.cpp +++ b/src/ripple/app/hook/impl/applyHook.cpp @@ -3548,15 +3548,20 @@ DEFINE_HOOK_FUNCTION( } +// these are only used by get_stobject_length below +enum parse_error : int32_t +{ + pe_unexpected_end = -1, + pe_unknown_type_early = -2, // detected early + pe_unknown_type_late = -3, // end of function + pe_excessive_nesting = -4, + pe_excessive_size = -5 +}; + // RH NOTE this is a light-weight stobject parsing function for drilling into a provided serialzied object // however it could probably be replaced by an existing class or routine or set of routines in XRPLD // Returns object length including header bytes (and footer bytes in the event of array or object) // negative indicates error -// -1 = unexpected end of bytes -// -2 = unknown type (detected early) -// -3 = unknown type (end of function) -// -4 = excessive stobject nesting -// -5 = excessively large array or object inline int32_t get_stobject_length ( unsigned char* start, // in - begin iterator unsigned char* maxptr, // in - end iterator @@ -3567,14 +3572,14 @@ inline int32_t get_stobject_length ( int recursion_depth = 0) // used internally { if (recursion_depth > 10) - return -4; + return pe_excessive_nesting; unsigned char* end = maxptr; unsigned char* upto = start; int high = *upto >> 4; int low = *upto & 0xF; - upto++; if (upto >= end) return -1; + upto++; if (upto >= end) return pe_unexpected_end; if (high > 0 && low > 0) { // common type common field @@ -3591,13 +3596,13 @@ inline int32_t get_stobject_length ( } else { // uncommon type and field type = *upto++; - if (upto >= end) return -1; + if (upto >= end) return pe_unexpected_end; field = *upto++; } DBG_PRINTF("%d get_st_object found field %d type %d\n", recursion_depth, field, type); - if (upto >= end) return -1; + if (upto >= end) return pe_unexpected_end; // RH TODO: link this to rippled's internal STObject constants // E.g.: @@ -3607,7 +3612,7 @@ inline int32_t get_stobject_length ( */ if (type < 1 || type > 19 || ( type >= 9 && type <= 13)) - return -2; + return pe_unknown_type_early; bool is_vl = (type == 8 /*ACCID*/ || type == 7 || type == 18 || type == 19); @@ -3617,7 +3622,7 @@ inline int32_t get_stobject_length ( { length = *upto++; if (upto >= end) - return -1; + return pe_unexpected_end; if (length < 193) { @@ -3626,12 +3631,12 @@ inline int32_t get_stobject_length ( { length -= 193; length *= 256; - length += *upto++ + 193; if (upto > end) return -1; + length += *upto++ + 193; if (upto > end) return pe_unexpected_end; } else { - int b2 = *upto++; if (upto >= end) return -1; + int b2 = *upto++; if (upto >= end) return pe_unexpected_end; length -= 241; length *= 65536; - length += 12481 + (b2 * 256) + *upto++; if (upto >= end) return -1; + length += 12481 + (b2 * 256) + *upto++; if (upto >= end) return pe_unexpected_end; } } else if ((type >= 1 && type <= 5) || type == 16 || type == 17 ) { @@ -3646,7 +3651,7 @@ inline int32_t get_stobject_length ( } else if (type == 6) /* AMOUNT */ { length = (*upto >> 6 == 1) ? 8 : 48; - if (upto >= end) return -1; + if (upto >= end) return pe_unexpected_end; } if (length > -1) @@ -3670,10 +3675,10 @@ inline int32_t get_stobject_length ( DBG_PRINTF("%d get_stobject_length i %d %d-%d, upto %d sublength %d\n", recursion_depth, i, subtype, subfield, upto - start, sublength); if (sublength < 0) - return -1; + return pe_unexpected_end; upto += sublength; if (upto >= end) - return -1; + return pe_unexpected_end; if ((*upto == 0xE1U && type == 0xEU) || (*upto == 0xF1U && type == 0xFU)) @@ -3683,10 +3688,10 @@ inline int32_t get_stobject_length ( return (upto - start); } } - return -5; + return pe_excessive_size; } - return -3; + return pe_unknown_type_late; }