Skip to content

Commit 8eca68e

Browse files
committed
[flang][runtime] Better handling for integer input into null address
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.
1 parent 9f7aac1 commit 8eca68e

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

flang-rt/lib/runtime/edit-input.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ static RT_API_ATTRS char ScanNumericPrefix(IoStatementState &io,
188188

189189
RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
190190
void *n, int kind, bool isSigned) {
191-
RUNTIME_CHECK(io.GetIoErrorHandler(), kind >= 1 && !(kind & (kind - 1)));
191+
auto &handler{io.GetIoErrorHandler()};
192+
RUNTIME_CHECK(handler, kind >= 1 && !(kind & (kind - 1)));
193+
if (!n) {
194+
handler.Crash("Null address for integer input item");
195+
}
192196
switch (edit.descriptor) {
193197
case DataEdit::ListDirected:
194198
if (IsNamelistNameOrSlash(io)) {
@@ -207,7 +211,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
207211
case 'A': // legacy extension
208212
return EditCharacterInput(io, edit, reinterpret_cast<char *>(n), kind);
209213
default:
210-
io.GetIoErrorHandler().SignalError(IostatErrorInFormat,
214+
handler.SignalError(IostatErrorInFormat,
211215
"Data edit descriptor '%c' may not be used with an INTEGER data item",
212216
edit.descriptor);
213217
return false;
@@ -217,7 +221,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
217221
auto fastField{io.GetUpcomingFastAsciiField()};
218222
char sign{ScanNumericPrefix(io, edit, next, remaining, &fastField)};
219223
if (sign == '-' && !isSigned) {
220-
io.GetIoErrorHandler().SignalError("Negative sign in UNSIGNED input field");
224+
handler.SignalError("Negative sign in UNSIGNED input field");
221225
return false;
222226
}
223227
common::uint128_t value{0};
@@ -254,8 +258,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
254258
break;
255259
}
256260
}
257-
io.GetIoErrorHandler().SignalError(
258-
"Bad character '%lc' in INTEGER input field", ch);
261+
handler.SignalError("Bad character '%lc' in INTEGER input field", ch);
259262
return false;
260263
}
261264
static constexpr auto maxu128OverTen{maxu128 / 10};
@@ -268,7 +271,7 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
268271
any = true;
269272
}
270273
if (!any && !remaining) {
271-
io.GetIoErrorHandler().SignalError(
274+
handler.SignalError(
272275
"Integer value absent from NAMELIST or list-directed input");
273276
return false;
274277
}
@@ -280,14 +283,14 @@ RT_API_ATTRS bool EditIntegerInput(IoStatementState &io, const DataEdit &edit,
280283
overflow |= value >= maxForKind;
281284
}
282285
if (overflow) {
283-
io.GetIoErrorHandler().SignalError(IostatIntegerInputOverflow,
286+
handler.SignalError(IostatIntegerInputOverflow,
284287
"Decimal input overflows INTEGER(%d) variable", kind);
285288
return false;
286289
}
287290
if (sign == '-') {
288291
value = -value;
289292
}
290-
if (any || !io.GetIoErrorHandler().InError()) {
293+
if (any || !handler.InError()) {
291294
// The value is stored in the lower order bits on big endian platform.
292295
// For memcpy, shift the value to the highest order bits.
293296
#if USING_NATIVE_INT128_T

0 commit comments

Comments
 (0)