Fix memory leaks and double frees (#3487)

This commit is contained in:
itchyny authored and GitHub committed 2026-03-01 06:15:58 +09:00
1 parent 2ad99a6c70
commit 750dbe723b
6 files changed
+30 -20

No files matched your search

+16 -6
View File
@@ -922,6 +922,8 @@ jv jq_next(jq_state *jq) {
if (!jv_is_valid(top)) {
if (jv_invalid_has_msg(jv_copy(top)))
set_error(jq, top);
else
jv_free(top);
goto do_backtrack;
}
@@ -1020,12 +1022,19 @@ jv jq_format_error(jv msg) {
// Invalid with msg; prefix with "jq: error: "
if (jv_get_kind(msg) != JV_KIND_INVALID) {
if (jv_get_kind(msg) == JV_KIND_STRING)
return jv_string_fmt("jq: error: %s", jv_string_value(msg));
if (jv_get_kind(msg) == JV_KIND_STRING) {
jv r = jv_string_fmt("jq: error: %s", jv_string_value(msg));
jv_free(msg);
return r;
}
msg = jv_dump_string(msg, JV_PRINT_INVALID);
if (jv_get_kind(msg) == JV_KIND_STRING)
return jv_string_fmt("jq: error: %s", jv_string_value(msg));
if (jv_get_kind(msg) == JV_KIND_STRING) {
jv r = jv_string_fmt("jq: error: %s", jv_string_value(msg));
jv_free(msg);
return r;
}
jv_free(msg);
return jq_format_error(jv_null()); // ENOMEM
}
@@ -1234,9 +1243,10 @@ int jq_compile_args(jq_state *jq, const char* str, jv args) {
int nerrors = load_program(jq, locations, &program);
if (nerrors == 0) {
nerrors = builtins_bind(jq, &program);
if (nerrors == 0) {
if (nerrors == 0)
nerrors = block_compile(program, &jq->bc, locations, args2obj(args));
}
else
jv_free(args);
} else
jv_free(args);
if (nerrors)
+2
View File
@@ -1746,6 +1746,7 @@ static int jvp_object_write(jv* object, jv key, jv **valpp) {
slot->value = jv_invalid();
} else {
if (!jvp_object_rehash(object)) {
jvp_string_free(key);
*valpp = NULL;
return 0;
}
@@ -1859,6 +1860,7 @@ jv jv_object_set(jv object, jv key, jv value) {
jv* slot;
if (!jvp_object_write(&object, key, &slot)) {
jv_free(object);
jv_free(value);
return jv_invalid_with_msg(jv_string("Object too big"));
}
jv_free(*slot);
+9 -13
View File
@@ -91,19 +91,15 @@ jv jv_get(jv t, jv k) {
v = jv_null();
} else {
double didx = jv_number_value(k);
if (jvp_number_is_nan(k)) {
if (didx < INT_MIN) didx = INT_MIN;
if (didx > INT_MAX) didx = INT_MAX;
int idx = (int)didx;
if (idx < 0)
idx += jv_array_length(jv_copy(t));
v = jv_array_get(t, idx);
if (!jv_is_valid(v)) {
jv_free(v);
v = jv_null();
} else {
if (didx < INT_MIN) didx = INT_MIN;
if (didx > INT_MAX) didx = INT_MAX;
int idx = (int)didx;
if (idx < 0)
idx += jv_array_length(jv_copy(t));
v = jv_array_get(t, idx);
if (!jv_is_valid(v)) {
jv_free(v);
v = jv_null();
}
}
}
jv_free(k);
@@ -163,6 +159,7 @@ jv jv_set(jv t, jv k, jv v) {
if (jvp_number_is_nan(k)) {
jv_free(t);
jv_free(k);
jv_free(v);
t = jv_invalid_with_msg(jv_string("Cannot set array element at NaN index"));
} else {
double didx = jv_number_value(k);
@@ -292,7 +289,6 @@ static jv jv_dels(jv t, jv keys) {
ends = jv_array_append(ends, jv_number(end));
} else {
jv_free(new_array);
jv_free(key);
new_array = e;
goto arr_out;
}
+1
View File
@@ -67,6 +67,7 @@ jv jv_load_file(const char* filename, int raw) {
data = value;
break;
}
jv_free(value);
}
}
if (!raw)
+1 -1
View File
@@ -16,7 +16,6 @@
#include "locfile.h"
#include "jv.h"
#include "jq.h"
#include "parser.h"
#include "util.h"
#include "compile.h"
#include "jv_alloc.h"
@@ -60,6 +59,7 @@ static jv build_lib_search_chain(jq_state *jq, jv search_path, jv jq_origin, jv
}
path = expand_path(path);
if (!jv_is_valid(path)) {
jv_free(err);
err = path;
path = jv_null();
continue;
+1
View File
@@ -607,6 +607,7 @@ int main(int argc, char* argv[]) {
if (!jv_is_valid(data)) {
data = jv_invalid_get_msg(data);
fprintf(stderr, "jq: %s\n", jv_string_value(data));
free(program_origin);
jv_free(data);
ret = JQ_ERROR_SYSTEM;
goto out;