Fixed process layer argument quoting; allows for strings with spaces. And added ability to specify a literal, in the style of python. (#1132)

This commit is contained in:
Adam 2022-10-09 22:53:48 -04:00 committed by GitHub
parent e7a575b4c4
commit dad0f79708
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 46 additions and 22 deletions

View File

@ -125,22 +125,26 @@ static int process_start(lua_State* L) {
int retval = 1;
size_t env_len = 0, key_len, val_len;
const char *cmd[256] = { NULL }, *env_names[256] = { NULL }, *env_values[256] = { NULL }, *cwd = NULL;
bool detach = false;
bool detach = false, literal = false;
int deadline = 10, new_fds[3] = { STDIN_FD, STDOUT_FD, STDERR_FD };
luaL_checktype(L, 1, LUA_TTABLE);
#if LUA_VERSION_NUM > 501
lua_len(L, 1);
#else
lua_pushinteger(L, (int)lua_objlen(L, 1));
#endif
size_t cmd_len = luaL_checknumber(L, -1); lua_pop(L, 1);
size_t arg_len = lua_gettop(L);
for (size_t i = 1; i <= cmd_len; ++i) {
lua_pushinteger(L, i);
lua_rawget(L, 1);
cmd[i-1] = luaL_checkstring(L, -1);
size_t arg_len = lua_gettop(L), cmd_len;
if (lua_type(L, 1) == LUA_TTABLE) {
#if LUA_VERSION_NUM > 501
lua_len(L, 1);
#else
lua_pushinteger(L, (int)lua_objlen(L, 1));
#endif
cmd_len = luaL_checknumber(L, -1); lua_pop(L, 1);
for (size_t i = 1; i <= cmd_len; ++i) {
lua_pushinteger(L, i);
lua_rawget(L, 1);
cmd[i-1] = luaL_checkstring(L, -1);
}
} else {
literal = true;
cmd[0] = luaL_checkstring(L, 1);
cmd_len = 1;
}
// this should never trip
// but if it does we are in deep trouble
assert(cmd[0]);
@ -239,15 +243,35 @@ static int process_start(lua_State* L) {
siStartInfo.hStdOutput = self->child_pipes[STDOUT_FD][1];
siStartInfo.hStdError = self->child_pipes[STDERR_FD][1];
char commandLine[32767] = { 0 }, environmentBlock[32767], wideEnvironmentBlock[32767*2];
strcpy(commandLine, cmd[0]);
int offset = 0;
for (size_t i = 1; i < cmd_len; ++i) {
size_t len = strlen(cmd[i]);
offset += len + 1;
if (offset >= sizeof(commandLine))
break;
strcat(commandLine, " ");
strcat(commandLine, cmd[i]);
if (!literal) {
for (size_t i = 0; i < cmd_len; ++i) {
size_t len = strlen(cmd[i]);
if (offset + len + 2 >= sizeof(commandLine)) break;
if (i > 0)
commandLine[offset++] = ' ';
commandLine[offset++] = '"';
int backslashCount = 0; // Yes, this is necessary.
for (size_t j = 0; j < len && offset + 2 + backslashCount < sizeof(commandLine); ++j) {
if (cmd[i][j] == '\\')
++backslashCount;
else if (cmd[i][j] == '"') {
for (size_t k = 0; k < backslashCount; ++k)
commandLine[offset++] = '\\';
commandLine[offset++] = '\\';
backslashCount = 0;
} else
backslashCount = 0;
commandLine[offset++] = cmd[i][j];
}
if (offset + 1 + backslashCount >= sizeof(commandLine)) break;
for (size_t k = 0; k < backslashCount; ++k)
commandLine[offset++] = '\\';
commandLine[offset++] = '"';
}
commandLine[offset] = 0;
} else {
strncpy(commandLine, cmd[0], sizeof(commandLine));
}
offset = 0;
for (size_t i = 0; i < env_len; ++i) {