Template
fix: address F2/F4 review findings (leaks, qsort guard, err contract, compiler-default layering)
This commit is contained in:
@@ -133,7 +133,6 @@ static const char CACHE_FUNCS[] =
|
|||||||
"# snippets read results via st_cache_get and record them via\n"
|
"# snippets read results via st_cache_get and record them via\n"
|
||||||
"# st_cache_set. Cache key: ac_cv_<checkname>_<compiler-id>.\n"
|
"# st_cache_set. Cache key: ac_cv_<checkname>_<compiler-id>.\n"
|
||||||
"\n"
|
"\n"
|
||||||
": \"${CC:=cc}\"\n"
|
|
||||||
": \"${CFLAGS:=}\"\n"
|
": \"${CFLAGS:=}\"\n"
|
||||||
": \"${st_cc_id:=unknown}\"\n"
|
": \"${st_cc_id:=unknown}\"\n"
|
||||||
": \"${cross_compiling:=}\"\n"
|
": \"${cross_compiling:=}\"\n"
|
||||||
|
|||||||
+8
-1
@@ -167,7 +167,13 @@ read_module_source(const char *path, char **out, size_t *out_len)
|
|||||||
return st_error_internal("extension load failed: out of memory");
|
return st_error_internal("extension load failed: out of memory");
|
||||||
}
|
}
|
||||||
got = fread(buf, 1, (size_t)size, f);
|
got = fread(buf, 1, (size_t)size, f);
|
||||||
if (got != (size_t)size || fclose(f) != 0) {
|
if (got != (size_t)size) {
|
||||||
|
/* short read: close BEFORE the error return (no leak) */
|
||||||
|
(void)fclose(f);
|
||||||
|
free(buf);
|
||||||
|
goto io_fail;
|
||||||
|
}
|
||||||
|
if (fclose(f) != 0) {
|
||||||
free(buf);
|
free(buf);
|
||||||
goto io_fail;
|
goto io_fail;
|
||||||
}
|
}
|
||||||
@@ -336,6 +342,7 @@ discover_dir(struct st_lua_rt *rt, const char *dir)
|
|||||||
free(names);
|
free(names);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
if (n > 1)
|
||||||
qsort(names, n, sizeof *names, cmp_str);
|
qsort(names, n, sizeof *names, cmp_str);
|
||||||
for (i = 0; i < n && err == NULL; i++) {
|
for (i = 0; i < n && err == NULL; i++) {
|
||||||
char *path;
|
char *path;
|
||||||
|
|||||||
+3
-3
@@ -388,8 +388,8 @@ static const char ARGS_PRE[] =
|
|||||||
"# Full argument parsing (todo 18): --help/-h, --version, --prefix/\n"
|
"# Full argument parsing (todo 18): --help/-h, --version, --prefix/\n"
|
||||||
"# --exec-prefix/--host/--build in both '=' and space forms, the\n"
|
"# --exec-prefix/--host/--build in both '=' and space forms, the\n"
|
||||||
"# per-option --enable-<name>/--disable-<name> flags, and generic\n"
|
"# per-option --enable-<name>/--disable-<name> flags, and generic\n"
|
||||||
"# VAR=VALUE overrides (positional, e.g. `./configure CC=clang`, or\n"
|
"# VAR=VALUE overrides (positional, e.g. `./configure VAR=VALUE`, or\n"
|
||||||
"# exported by the invoking shell, e.g. `CC=clang ./configure`).\n"
|
"# exported by the invoking shell, e.g. `VAR=VALUE ./configure`).\n"
|
||||||
"# Unknown --* options error. The loop only READS \"$@\", so the\n"
|
"# Unknown --* options error. The loop only READS \"$@\", so the\n"
|
||||||
"# config.log init right after this section still sees the complete\n"
|
"# config.log init right after this section still sees the complete\n"
|
||||||
"# original invocation.\n"
|
"# original invocation.\n"
|
||||||
@@ -414,7 +414,7 @@ static const char USAGE_HEAD[] =
|
|||||||
" printf '%s\\n' ' differs from --build -> cross-compiling'\n"
|
" printf '%s\\n' ' differs from --build -> cross-compiling'\n"
|
||||||
" printf '%s\\n' ' --build=TRIPLET, --build TRIPLET'\n"
|
" printf '%s\\n' ' --build=TRIPLET, --build TRIPLET'\n"
|
||||||
" printf '%s\\n' ' the platform the build is running on'\n"
|
" printf '%s\\n' ' the platform the build is running on'\n"
|
||||||
" printf '%s\\n' ' VAR=VALUE override the variable VAR (e.g. CC=clang);'\n"
|
" printf '%s\\n' ' VAR=VALUE override a variable before substitution;'\n"
|
||||||
" printf '%s\\n' ' both VAR=VALUE ./configure and'\n"
|
" printf '%s\\n' ' both VAR=VALUE ./configure and'\n"
|
||||||
" printf '%s\\n' ' ./configure VAR=VALUE work'\n";
|
" printf '%s\\n' ' ./configure VAR=VALUE work'\n";
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -91,9 +91,13 @@ struct st_kdl_document {
|
|||||||
|
|
||||||
/* Parse `src` (a NUL-terminated buffer, borrowed) into an AST. On success
|
/* Parse `src` (a NUL-terminated buffer, borrowed) into an AST. On success
|
||||||
* returns the document — possibly with zero nodes — and leaves `*err`
|
* returns the document — possibly with zero nodes — and leaves `*err`
|
||||||
* untouched. On failure returns NULL and, if `err != NULL`, sets `*err`
|
* untouched. On failure returns NULL and sets `*err` to an owned st_error
|
||||||
* to an owned st_error of category ST_ERR_KDL_PARSE with a stable span
|
* of category ST_ERR_KDL_PARSE with a stable span (see the header
|
||||||
* (see the header comment). `filename` is borrowed into every span. */
|
* comment). `err` is REQUIRED: it must point to a valid
|
||||||
|
* `struct st_error *` — every caller passes `&err`. NULL is tolerated
|
||||||
|
* only as a last-resort fallback (the diagnostic is then discarded, and
|
||||||
|
* the document is still NULL on failure), but no new caller should rely
|
||||||
|
* on it. `filename` is borrowed into every span. */
|
||||||
struct st_kdl_document *st_kdl_parse(const char *src, const char *filename,
|
struct st_kdl_document *st_kdl_parse(const char *src, const char *filename,
|
||||||
struct st_error **err);
|
struct st_error **err);
|
||||||
|
|
||||||
|
|||||||
+9
-2
@@ -621,10 +621,14 @@ st_kdl_parse(const char *src, const char *filename, struct st_error **err)
|
|||||||
struct st_kdl_document *doc;
|
struct st_kdl_document *doc;
|
||||||
struct st_kdl_node *head = NULL;
|
struct st_kdl_node *head = NULL;
|
||||||
struct st_kdl_node *tail = NULL;
|
struct st_kdl_node *tail = NULL;
|
||||||
|
struct st_error *local_err = NULL;
|
||||||
|
|
||||||
if (err != NULL) {
|
if (err == NULL) {
|
||||||
*err = NULL;
|
/* last-resort fallback: the documented contract requires a
|
||||||
|
* non-NULL err; a NULL caller discards the diagnostic */
|
||||||
|
err = &local_err;
|
||||||
}
|
}
|
||||||
|
*err = NULL;
|
||||||
|
|
||||||
parser.lx = st_lexer_new(src, filename);
|
parser.lx = st_lexer_new(src, filename);
|
||||||
if (parser.lx == NULL) {
|
if (parser.lx == NULL) {
|
||||||
@@ -684,6 +688,9 @@ fail:
|
|||||||
st_lexer_free(parser.lx);
|
st_lexer_free(parser.lx);
|
||||||
nodes_free(head);
|
nodes_free(head);
|
||||||
free(doc);
|
free(doc);
|
||||||
|
if (err == &local_err && local_err != NULL) {
|
||||||
|
st_error_free(local_err);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-3
@@ -109,7 +109,21 @@ read_file(const char *path, char **out)
|
|||||||
return st_error_internal("out of memory");
|
return st_error_internal("out of memory");
|
||||||
}
|
}
|
||||||
got = fread(buf, 1, (size_t)size, f);
|
got = fread(buf, 1, (size_t)size, f);
|
||||||
if (got != (size_t)size || fclose(f) != 0) {
|
if (got != (size_t)size) {
|
||||||
|
/* short read: close BEFORE the error return (no leak) */
|
||||||
|
(void)fclose(f);
|
||||||
|
free(buf);
|
||||||
|
need = strlen(path) + 64;
|
||||||
|
buf = malloc(need);
|
||||||
|
if (buf == NULL)
|
||||||
|
return st_error_internal("out of memory");
|
||||||
|
(void)snprintf(buf, need, "cannot read build file '%s': %s",
|
||||||
|
path, strerror(errno));
|
||||||
|
err = st_error_io(buf);
|
||||||
|
free(buf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (fclose(f) != 0) {
|
||||||
free(buf);
|
free(buf);
|
||||||
need = strlen(path) + 64;
|
need = strlen(path) + 64;
|
||||||
buf = malloc(need);
|
buf = malloc(need);
|
||||||
@@ -205,8 +219,11 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
const char *cc = st_registry_get_var(st_ext_var_registry(ctx),
|
const char *cc = st_registry_get_var(st_ext_var_registry(ctx),
|
||||||
"CC");
|
"CC");
|
||||||
printf("wrote ./configure (CC=%s)\n",
|
|
||||||
cc != NULL ? cc : "cc");
|
if (cc != NULL)
|
||||||
|
printf("wrote ./configure (CC=%s)\n", cc);
|
||||||
|
else
|
||||||
|
printf("wrote ./configure\n");
|
||||||
}
|
}
|
||||||
rc = CLI_EXIT_OK;
|
rc = CLI_EXIT_OK;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user