From 32145a5e18f87e4f672bbc051f00b8d57be98eb3 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Fri, 18 Apr 2025 12:51:18 -0700 Subject: [PATCH] [flang][runtime] Better handling for integer input into null address (#135987) The original descriptor-only path for I/O checks for null data addresses and crashes with a readable message, but there's no such check on the new fast path for formatted integer input, and so a READ into (say) a deallocated allocatable will crash with a segfault. Put a null data address check on the new fast path. --- flang-rt/lib/runtime/edit-input.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/flang-rt/lib/runtime/edit-input.cpp b/flang-rt/lib/runtime/edit-input.cpp index 4aa8c70f776c..68ea34bf63cc 100644 --- a/flang-rt/lib/runtime/edit-input.cpp +++ b/flang-rt/lib/runtime/edit-input.cpp @@ -188,7 +188,11 @@ static RT_API_ATTRS char ScanNumericPrefix(IoStatementState &io, RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit, void *n, int kind, bool isSigned) { - RUNTIME_CHECK(io.GetIoErrorHandler(), kind >= 1 && !(kind & (kind - 1))); + auto &handler{io.GetIoErrorHandler()}; + RUNTIME_CHECK(handler, kind >= 1 && !(kind & (kind - 1))); + if (!n) { + handler.Crash("Null address for integer input item"); + } switch (edit.descriptor) { case DataEdit::ListDirected: if (IsNamelistNameOrSlash(io)) { @@ -207,7 +211,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit, case 'A': // legacy extension return EditCharacterInput(io, edit, reinterpret_cast(n), kind); default: - io.GetIoErrorHandler().SignalError(IostatErrorInFormat, + handler.SignalError(IostatErrorInFormat, "Data edit descriptor '%c' may not be used with an INTEGER data item", edit.descriptor); return false; @@ -217,7 +221,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit, auto fastField{io.GetUpcomingFastAsciiField()}; char sign{ScanNumericPrefix(io, edit, next, remaining, &fastField)}; if (sign == '-' && !isSigned) { - io.GetIoErrorHandler().SignalError("Negative sign in UNSIGNED input field"); + handler.SignalError("Negative sign in UNSIGNED input field"); return false; } common::uint128_t value{0}; @@ -254,8 +258,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit, break; } } - io.GetIoErrorHandler().SignalError( - "Bad character '%lc' in INTEGER input field", ch); + handler.SignalError("Bad character '%lc' in INTEGER input field", ch); return false; } static constexpr auto maxu128OverTen{maxu128 / 10}; @@ -268,7 +271,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit, any = true; } if (!any && !remaining) { - io.GetIoErrorHandler().SignalError( + handler.SignalError( "Integer value absent from NAMELIST or list-directed input"); return false; } @@ -280,14 +283,14 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit, overflow |= value >= maxForKind; } if (overflow) { - io.GetIoErrorHandler().SignalError(IostatIntegerInputOverflow, + handler.SignalError(IostatIntegerInputOverflow, "Decimal input overflows INTEGER(%d) variable", kind); return false; } if (sign == '-') { value = -value; } - if (any || !io.GetIoErrorHandler().InError()) { + if (any || !handler.InError()) { // The value is stored in the lower order bits on big endian platform. // For memcpy, shift the value to the highest order bits. #if USING_NATIVE_INT128_T