Dont use VLAs in launcher.c

This commit is contained in:
Kovid Goyal 2021-02-19 15:04:49 +05:30
parent 9cd8637e9c
commit d45a8309cb
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -69,16 +69,19 @@ typedef struct {
static bool static bool
canonicalize_path(const char *srcpath, char *dstpath, size_t sz) { canonicalize_path(const char *srcpath, char *dstpath, size_t sz) {
// remove . and .. path segments // remove . and .. path segments
bool ok = false;
size_t plen = strlen(srcpath) + 1, chk; size_t plen = strlen(srcpath) + 1, chk;
char wtmp[plen], *tokv[plen], *s, *tok, *sav; char *wtmp = malloc(plen);
int i, ti, relpath; char **tokv = malloc(sizeof(char*) * plen);
if (!wtmp || !tokv) goto end;
char *s, *tok, *sav;
bool relpath = *srcpath != '/';
relpath = (*srcpath == '/') ? 0 : 1;
ti = 0;
// use a buffer as strtok modifies its input // use a buffer as strtok modifies its input
(void) strcpy(wtmp, srcpath); memcpy(wtmp, srcpath, plen);
tok = strtok_r(wtmp, "/", &sav); tok = strtok_r(wtmp, "/", &sav);
int ti = 0;
while (tok != NULL) { while (tok != NULL) {
if (strcmp(tok, "..") == 0) { if (strcmp(tok, "..") == 0) {
if (ti > 0) ti--; if (ti > 0) ti--;
@ -90,28 +93,31 @@ canonicalize_path(const char *srcpath, char *dstpath, size_t sz) {
chk = 0; chk = 0;
s = dstpath; s = dstpath;
for (i = 0; i < ti; i++) { for (int i = 0; i < ti; i++) {
size_t l = strlen(tokv[i]); size_t token_sz = strlen(tokv[i]);
if (i > 0 || !relpath) { if (i > 0 || !relpath) {
if (++chk >= sz) return false; if (++chk >= sz) goto end;
*s++ = '/'; *s++ = '/';
} }
chk += l; chk += token_sz;
if (chk >= sz) return -1; if (chk >= sz) goto end;
strcpy(s, tokv[i]); memcpy(s, tokv[i], token_sz);
s += l; s += token_sz;
} }
if (s == dstpath) { if (s == dstpath) {
if (++chk >= sz) return -1; if (++chk >= sz) goto end;
*s++ = relpath ? '.' : '/'; *s++ = relpath ? '.' : '/';
} }
*s = '\0'; *s = '\0';
ok = true;
return true; end:
free(wtmp); free(tokv);
return ok;
} }
static bool static bool
@ -158,6 +164,7 @@ static int
free_argv(wchar_t **argv) { free_argv(wchar_t **argv) {
wchar_t **p = argv; wchar_t **p = argv;
while (*p) { PyMem_RawFree(*p); p++; } while (*p) { PyMem_RawFree(*p); p++; }
free(argv);
return 1; return 1;
} }
@ -169,7 +176,8 @@ run_embedded(const RunData run_data) {
#endif #endif
if (!set_xoptions(run_data.exe_dir, run_data.lc_ctype, from_source)) return 1; if (!set_xoptions(run_data.exe_dir, run_data.lc_ctype, from_source)) return 1;
int argc = run_data.argc + 1; int argc = run_data.argc + 1;
wchar_t *argv[argc]; wchar_t **argv = calloc(argc, sizeof(wchar_t*));
if (!argv) { fprintf(stderr, "Out of memory creating argv\n"); return 1; }
memset(argv, 0, sizeof(wchar_t*) * argc); memset(argv, 0, sizeof(wchar_t*) * argc);
argv[0] = Py_DecodeLocale(run_data.exe, NULL); argv[0] = Py_DecodeLocale(run_data.exe, NULL);
if (!argv[0]) { fprintf(stderr, "Failed to decode path to exe\n"); return free_argv(argv); } if (!argv[0]) { fprintf(stderr, "Failed to decode path to exe\n"); return free_argv(argv); }
@ -181,6 +189,7 @@ run_embedded(const RunData run_data) {
} }
int ret = Py_Main(argc, argv); int ret = Py_Main(argc, argv);
// we cannot free argv properly as Py_Main modifies it // we cannot free argv properly as Py_Main modifies it
free(argv);
return ret; return ret;
} }