reject out-of-range array index in const json_pointer access - #5327
reject out-of-range array index in const json_pointer access#5327Angadi56 wants to merge 1 commit into
Conversation
Signed-off-by: Angadi Yashaswini <angadi@digiscrypt.com>
nlohmann
left a comment
There was a problem hiding this comment.
But operator[] is not supposed to do range checks - this is what at() is for. Or what am I missing?
|
You're right on the general contract, and I'd agree without argument if this were What made me file it is that the const json_pointer overload isn't actually unchecked today. A few lines above this hunk the same function throws It also differs from Where the line sits is your call though. If you'd rather keep |
The const
operator[](json_pointer)overload resolves an array reference token withptr->operator[](array_index(token)), which lands on the constoperator[](size_type), a barestd::vector::operator[]with no range check.array_index()accepts any decimal in0 .. SIZE_MAX-1, so on{"a":[1,2,3]}a pointer like/a/5computesarray->data() + idx * sizeof(basic_json)and hands back a const reference built from whatever heap bytes follow the array. AddressSanitizer reports a heap-buffer-overflow read there. Since the type byte and thejson_valueunion are then read from unrelated memory, a type byte that happens to land onobject/array/string/binarymakes the following 8 bytes get used as a pointer and dereferenced.The check belongs in
get_unchecked()rather than at the call site: a caller passes a string, so it cannot tell whether a token is in range without resolving the pointer itself. The same function already throwsout_of_range.402for-, which is likewise an index past the end, andget_checked()a few lines below performs exactly theidx >= size()test that was missing here, so this mirrors it and reuses its 401 message. That makesj["/a/5"_json_pointer]report whatj.at("/a/5"_json_pointer)already reports for the same pointer. In-range pointers resolve unchanged, and the non-const overload keeps filling the array with nulls as documented.Verified with the full test suite (109/109) plus
make check-amalgamationandcpplint. The new checks inunit-json_pointer.cppfail on develop and pass here.make amalgamate.Read the Contribution Guidelines for detailed information.