Skip to content

Commit 4d0d1c6

Browse files
committed
add runtime kind code check for ExecuteCommandLine
1 parent 18a48ef commit 4d0d1c6

File tree

4 files changed

+57
-4
lines changed

4 files changed

+57
-4
lines changed

flang/runtime/execute.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,22 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
122122

123123
if (exitstat) {
124124
RUNTIME_CHECK(terminator, IsValidIntDescriptor(exitstat));
125+
auto exitstatKind{exitstat->type().GetCategoryAndKind()->second};
126+
if (exitstatKind < 4) {
127+
terminator.Crash("exitstat must have an integer kind greater or equal to "
128+
"4 but have: %d",
129+
exitstatKind);
130+
}
125131
}
126132

127133
if (cmdstat) {
128-
RUNTIME_CHECK(terminator, IsValidIntDescriptor(cmdstat));
134+
RUNTIME_CHECK(terminator, IsValidIntDescriptor(cmdstat, 0));
135+
auto cmdstatKind{cmdstat->type().GetCategoryAndKind()->second};
136+
if (cmdstatKind < 2) {
137+
terminator.Crash("cmdstat must have an integer kind greater or equal to "
138+
"2 but have: %d",
139+
cmdstatKind);
140+
}
129141
// Assigned 0 as specifed in standard, if error then overwrite
130142
StoreIntToDescriptor(cmdstat, CMD_EXECUTED, terminator);
131143
}

flang/runtime/tools.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <cstdint>
1313
#include <cstdlib>
1414
#include <cstring>
15+
#include <stdio.h>
1516

1617
namespace Fortran::runtime {
1718

@@ -191,12 +192,13 @@ RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value) {
191192
value->rank() == 0;
192193
}
193194

194-
RT_API_ATTRS bool IsValidIntDescriptor(const Descriptor *intVal) {
195+
RT_API_ATTRS bool IsValidIntDescriptor(
196+
const Descriptor *intVal, const int minIntKind) {
195197
// Check that our descriptor is allocated and is a scalar integer with
196198
// kind != 1 (i.e. with a large enough decimal exponent range).
197199
return intVal && intVal->IsAllocated() && intVal->rank() == 0 &&
198200
intVal->type().IsInteger() && intVal->type().GetCategoryAndKind() &&
199-
intVal->type().GetCategoryAndKind()->second != 1;
201+
intVal->type().GetCategoryAndKind()->second > minIntKind;
200202
}
201203

202204
RT_API_ATTRS std::int32_t CopyCharsToDescriptor(const Descriptor &value,

flang/runtime/tools.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,8 @@ RT_API_ATTRS char *EnsureNullTerminated(
446446

447447
RT_API_ATTRS bool IsValidCharDescriptor(const Descriptor *value);
448448

449-
RT_API_ATTRS bool IsValidIntDescriptor(const Descriptor *intVal);
449+
RT_API_ATTRS bool IsValidIntDescriptor(
450+
const Descriptor *intVal, const int minIntKind = 1);
450451

451452
// Copy a null-terminated character array \p rawValue to descriptor \p value.
452453
// The copy starts at the given \p offset, if not present then start at 0.

flang/unittests/Runtime/CommandTest.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,44 @@ TEST_F(ZeroArguments, ECLInvalidCommandAsyncDontAffectAsync) {
422422
*command.get(), false, nullptr, nullptr, nullptr));
423423
}
424424

425+
TEST_F(ZeroArguments, ECLBadKindError) {
426+
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
427+
bool wait{true};
428+
OwningPtr<Descriptor> exitStat{EmptyIntDescriptor<sizeof(std::int16_t)>()};
429+
OwningPtr<Descriptor> cmdStat{EmptyIntDescriptor<sizeof(std::int8_t)>()};
430+
431+
EXPECT_DEATH(RTNAME(ExecuteCommandLine)(
432+
*command.get(), wait, exitStat.get(), nullptr, nullptr),
433+
"exitstat must have an integer kind greater or equal to 4 but have: 2");
434+
EXPECT_DEATH(RTNAME(ExecuteCommandLine)(
435+
*command.get(), wait, nullptr, cmdStat.get(), nullptr),
436+
"cmdstat must have an integer kind greater or equal to 2 but have: 1");
437+
}
438+
439+
TEST_F(ZeroArguments, ECLGoodKindEqual) {
440+
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
441+
bool wait{true};
442+
OwningPtr<Descriptor> exitStat{EmptyIntDescriptor<sizeof(std::int32_t)>()};
443+
OwningPtr<Descriptor> cmdStat{EmptyIntDescriptor<sizeof(std::int16_t)>()};
444+
445+
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
446+
*command.get(), wait, exitStat.get(), nullptr, nullptr));
447+
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
448+
*command.get(), wait, nullptr, cmdStat.get(), nullptr));
449+
}
450+
451+
TEST_F(ZeroArguments, ECLGoodKindGreater) {
452+
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
453+
bool wait{true};
454+
OwningPtr<Descriptor> exitStat{EmptyIntDescriptor<sizeof(std::int64_t)>()};
455+
OwningPtr<Descriptor> cmdStat{EmptyIntDescriptor<sizeof(std::int32_t)>()};
456+
457+
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
458+
*command.get(), wait, exitStat.get(), nullptr, nullptr));
459+
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
460+
*command.get(), wait, nullptr, cmdStat.get(), nullptr));
461+
}
462+
425463
static const char *oneArgArgv[]{"aProgram", "anArgumentOfLength20"};
426464
class OneArgument : public CommandFixture {
427465
protected:

0 commit comments

Comments
 (0)