Skip to content

Commit 9a73cb8

Browse files
committed
required parameter use reference not pointer, ensure command is null-terminated
1 parent d821529 commit 9a73cb8

File tree

3 files changed

+32
-15
lines changed

3 files changed

+32
-15
lines changed

flang/include/flang/Runtime/command.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ std::int32_t RTNAME(GetEnvVariable)(const Descriptor &name,
5757
const char *sourceFile = nullptr, int line = 0);
5858

5959
// Calls std::system()
60-
void RTNAME(System)(const Descriptor *command = nullptr,
60+
void RTNAME(System)(const Descriptor &command,
6161
const Descriptor *exitstat = nullptr, const char *sourceFile = nullptr,
6262
int line = 0);
6363
}

flang/runtime/command.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -282,22 +282,39 @@ std::int32_t RTNAME(GetEnvVariable)(const Descriptor &name,
282282
return StatOk;
283283
}
284284

285-
void RTNAME(System)(const Descriptor *command, const Descriptor *exitstat,
285+
const char *ensureNullTerminated(
286+
const char *str, size_t length, Terminator &terminator) {
287+
if (length < strlen(str)) {
288+
char *newCmd{(char *)malloc(length + 1)};
289+
if (newCmd == NULL) {
290+
terminator.Crash("Command not null-terminated, memory allocation failed "
291+
"for null-terminated newCmd.");
292+
}
293+
294+
strncpy(newCmd, str, length);
295+
newCmd[length] = '\0';
296+
return newCmd;
297+
} else {
298+
return str;
299+
}
300+
}
301+
302+
void RTNAME(System)(const Descriptor &command, const Descriptor *exitstat,
286303
const char *sourceFile, int line) {
287304
Terminator terminator{sourceFile, line};
288305

289-
if (command) {
290-
RUNTIME_CHECK(terminator, IsValidCharDescriptor(command));
291-
int status{std::system(command->OffsetElement())};
292-
if (exitstat) {
293-
RUNTIME_CHECK(terminator, IsValidIntDescriptor(exitstat));
306+
const char *newCmd{ensureNullTerminated(
307+
command.OffsetElement(), command.ElementBytes(), terminator)};
308+
int status{std::system(newCmd)};
309+
310+
if (exitstat) {
311+
RUNTIME_CHECK(terminator, IsValidIntDescriptor(exitstat));
294312
#ifdef _WIN32
295-
StoreLengthToDescriptor(exitstat, status, terminator);
313+
StoreLengthToDescriptor(exitstat, status, terminator);
296314
#else
297-
int exitstatVal{WEXITSTATUS(status)};
298-
StoreLengthToDescriptor(exitstat, exitstatVal, terminator);
315+
int exitstatVal{WEXITSTATUS(status)};
316+
StoreLengthToDescriptor(exitstat, exitstatVal, terminator);
299317
#endif
300-
}
301318
}
302319
}
303320

flang/unittests/Runtime/CommandTest.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,15 +242,15 @@ TEST_F(ZeroArguments, SystemValidCommandExitStat) {
242242
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
243243
OwningPtr<Descriptor> exitStat{EmptyIntDescriptor()};
244244

245-
RTNAME(System)(command.get(), exitStat.get());
245+
RTNAME(System)(*command.get(), exitStat.get());
246246
CheckDescriptorEqInt(exitStat.get(), 0);
247247
}
248248

249249
TEST_F(ZeroArguments, SystemInvalidCommandExitStat) {
250250
OwningPtr<Descriptor> command{CharDescriptor("InvalidCommand")};
251251
OwningPtr<Descriptor> exitStat{EmptyIntDescriptor()};
252252

253-
RTNAME(System)(command.get(), exitStat.get());
253+
RTNAME(System)(*command.get(), exitStat.get());
254254
#ifdef _WIN32
255255
CheckDescriptorEqInt(exitStat.get(), 1);
256256
#else
@@ -260,12 +260,12 @@ TEST_F(ZeroArguments, SystemInvalidCommandExitStat) {
260260

261261
TEST_F(ZeroArguments, SystemValidCommandOptionalExitStat) {
262262
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
263-
EXPECT_NO_FATAL_FAILURE(RTNAME(System)(command.get(), nullptr));
263+
EXPECT_NO_FATAL_FAILURE(RTNAME(System)(*command.get(), nullptr));
264264
}
265265

266266
TEST_F(ZeroArguments, SystemInvalidCommandOptionalExitStat) {
267267
OwningPtr<Descriptor> command{CharDescriptor("InvalidCommand")};
268-
EXPECT_NO_FATAL_FAILURE(RTNAME(System)(command.get(), nullptr));
268+
EXPECT_NO_FATAL_FAILURE(RTNAME(System)(*command.get(), nullptr));
269269
}
270270

271271
static const char *oneArgArgv[]{"aProgram", "anArgumentOfLength20"};

0 commit comments

Comments
 (0)