[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.
This commit is contained in:
parent
6a7044a7b8
commit
32145a5e18
@ -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<char *>(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
|
||||
|
Loading…
x
Reference in New Issue
Block a user