AVRO-3194: [c++] Throw instead of segfaulting on GenericDatum::value<T>() type mismatch - #3965
Open
iemejia wants to merge 1 commit into
Open
AVRO-3194: [c++] Throw instead of segfaulting on GenericDatum::value<T>() type mismatch#3965iemejia wants to merge 1 commit into
iemejia wants to merge 1 commit into
Conversation
…T>() type mismatch GenericDatum::value<T>() returned *std::any_cast<T>(&value_). When the requested C++ type T does not match the type actually stored in the datum, std::any_cast on a pointer returns nullptr, so dereferencing it is an unchecked null-pointer dereference (CWE-476) that leads to undefined behaviour and a segmentation fault (e.g. const GenericRecord r = datum.value<GenericRecord>() when the datum does not hold a GenericRecord). Guard both the mutable and const overloads: throw an avro::Exception on a type mismatch instead of dereferencing the null pointer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this pull request?
GenericDatum::value<T>()(both the mutable and const overloads) returned:The pointer form of
std::any_cast<T>(&value_)returnsnullptrwhen the requested C++ typeTdoes not match the type actually held by the datum. Dereferencing that result is an unchecked null-pointer dereference (CWE-476): undefined behaviour that manifests as a segmentation fault as soon as the returned reference is read or copied.This is the crash reported in AVRO-3194, where user code that binds/copies the result — e.g.
const avro::GenericRecord record = datum.value<avro::GenericRecord>()when the datum is not actually aGenericRecord— segfaults instead of receiving a diagnosable error.How was this patch fixed?
Both overloads now check the
any_castresult and throw anavro::Exceptiondescribing the datum type on a mismatch, instead of dereferencing a null pointer. Correct-type access and the union-unwrapping path are unchanged.How was this patch tested?
New regression case
testGenericDatumValueTypeMismatchintest/unittest.cc:value<int32_t>()/value<std::vector<uint8_t>>()on a string datum) now throwsavro::Exceptionthrough both the mutable and const overloads.Verified against the current code: without the fix the test reports
exception avro::Exception expected but not raised(the null reference is UB and segfaults when the value is copied, as in the report); with the fix the fullunittestsuite passes (*** No errors detected).