Compare commits

...

No commits in common. "c8s" and "c10s" have entirely different histories.
c8s ... c10s

19 changed files with 352 additions and 33658 deletions

5
.gitignore vendored
View File

@ -1,2 +1,5 @@
SOURCES/jq-1.6.tar.gz /jq-1.3.tar.gz
/jq-1.5.tar.gz
/jq-1.6.tar.gz /jq-1.6.tar.gz
/jq-1.7.tar.gz
/jq-1.7.1.tar.gz

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,19 @@
diff -up jq-1.6/src/jv_aux.c.orig jq-1.6/src/jv_aux.c Based on:
--- jq-1.6/src/jv_aux.c.orig 2025-06-30 18:14:49.211823479 +0200
+++ jq-1.6/src/jv_aux.c 2025-06-30 18:15:20.270512946 +0200 commit de21386681c0df0104a99d9d09db23a9b2a78b1e
@@ -162,18 +162,19 @@ jv jv_set(jv t, jv k, jv v) { Author: itchyny <itchyny@cybozu.co.jp>
Date: Wed May 21 07:45:00 2025 +0900
Fix signed integer overflow in jvp_array_write and jvp_object_rehash
This commit fixes signed integer overflow and SEGV issues on growing
arrays and objects. The size of arrays and objects is now limited to
`536870912` (`0x20000000`). This fixes CVE-2024-23337 and fixes #3262.
diff -up jq-jq-1.7.1/src/jv_aux.c.orig jq-jq-1.7.1/src/jv_aux.c
--- jq-jq-1.7.1/src/jv_aux.c.orig 2023-12-13 20:20:22.000000000 +0100
+++ jq-jq-1.7.1/src/jv_aux.c 2025-06-25 10:10:45.542441628 +0200
@@ -193,18 +193,19 @@ jv jv_set(jv t, jv k, jv v) {
if (slice_len < insert_len) { if (slice_len < insert_len) {
// array is growing // array is growing
int shift = insert_len - slice_len; int shift = insert_len - slice_len;
@ -25,45 +37,10 @@ diff -up jq-1.6/src/jv_aux.c.orig jq-1.6/src/jv_aux.c
t = jv_array_set(t, start + i, jv_array_get(jv_copy(v), i)); t = jv_array_set(t, start + i, jv_array_get(jv_copy(v), i));
} }
jv_free(v); jv_free(v);
diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c diff -up jq-jq-1.7.1/src/jv.c.orig jq-jq-1.7.1/src/jv.c
--- jq-1.6/src/jv.c.orig 2025-06-30 18:14:49.221499541 +0200 --- jq-jq-1.7.1/src/jv.c.orig 2025-06-25 10:07:24.630147714 +0200
+++ jq-1.6/src/jv.c 2025-06-30 18:17:11.071456789 +0200 +++ jq-jq-1.7.1/src/jv.c 2025-06-25 10:12:28.591914084 +0200
@@ -326,10 +326,10 @@ static double jvp_literal_number_to_doub @@ -1001,6 +1001,11 @@ jv jv_array_set(jv j, int idx, jv val) {
decNumber *p_dec_number = jvp_dec_number_ptr(j);
decNumberDoublePrecision dec_double;
- char literal[BIN64_DEC_PRECISION + DEC_NUMBER_STRING_GUARD + 1];
+ char literal[BIN64_DEC_PRECISION + DEC_NUMBER_STRING_GUARD + 1];
// reduce the number to the shortest possible form
- // while also making sure than no more than BIN64_DEC_PRECISION
+ // while also making sure than no more than BIN64_DEC_PRECISION
// digits are used (dec_context_to_double)
decNumberReduce(&dec_double.number, p_dec_number, DEC_CONTEXT_TO_DOUBLE());
@@ -368,7 +368,7 @@ static const char* jvp_literal_number_li
// Preserve the actual precision as we have parsed it
// don't do decNumberTrim(pdec);
-
+
decNumberToString(pdec, plit->literal_data);
}
@@ -459,9 +459,9 @@ int jvp_number_cmp(jv a, jv b) {
assert(JVP_HAS_KIND(b, JV_KIND_NUMBER));
if(JVP_HAS_FLAGS(a, JVP_FLAGS_NUMBER_LITERAL) && JVP_HAS_FLAGS(b, JVP_FLAGS_NUMBER_LITERAL)) {
- decNumberSingle res;
- decNumberCompare(&res.number,
- jvp_dec_number_ptr(a),
+ decNumberSingle res;
+ decNumberCompare(&res.number,
+ jvp_dec_number_ptr(a),
jvp_dec_number_ptr(b),
DEC_CONTEXT()
);
@@ -703,6 +703,11 @@ jv jv_array_set(jv j, int idx, jv val) {
jv_free(val); jv_free(val);
return jv_invalid_with_msg(jv_string("Out of bounds negative array index")); return jv_invalid_with_msg(jv_string("Out of bounds negative array index"));
} }
@ -75,7 +52,7 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
// copy/free of val,j coalesced // copy/free of val,j coalesced
jv* slot = jvp_array_write(&j, idx); jv* slot = jvp_array_write(&j, idx);
jv_free(*slot); jv_free(*slot);
@@ -722,6 +727,7 @@ jv jv_array_concat(jv a, jv b) { @@ -1020,6 +1025,7 @@ jv jv_array_concat(jv a, jv b) {
// FIXME: could be faster // FIXME: could be faster
jv_array_foreach(b, i, elem) { jv_array_foreach(b, i, elem) {
a = jv_array_append(a, elem); a = jv_array_append(a, elem);
@ -83,15 +60,15 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
} }
jv_free(b); jv_free(b);
return a; return a;
@@ -992,6 +998,7 @@ jv jv_string_indexes(jv j, jv k) { @@ -1292,6 +1298,7 @@ jv jv_string_indexes(jv j, jv k) {
p = jstr; p = jstr;
while ((p = _jq_memmem(p, (jstr + jlen) - p, idxstr, idxlen)) != NULL) { while ((p = _jq_memmem(p, (jstr + jlen) - p, idxstr, idxlen)) != NULL) {
a = jv_array_append(a, jv_number(p - jstr)); a = jv_array_append(a, jv_number(p - jstr));
+ if (!jv_is_valid(a)) break; + if (!jv_is_valid(a)) break;
p += idxlen; p++;
} }
jv_free(j); }
@@ -1013,14 +1020,17 @@ jv jv_string_split(jv j, jv sep) { @@ -1314,14 +1321,17 @@ jv jv_string_split(jv j, jv sep) {
if (seplen == 0) { if (seplen == 0) {
int c; int c;
@ -110,7 +87,7 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
// Add an empty string to denote that j ends on a sep // Add an empty string to denote that j ends on a sep
if (s + seplen == jend && seplen != 0) if (s + seplen == jend && seplen != 0)
a = jv_array_append(a, jv_string("")); a = jv_array_append(a, jv_string(""));
@@ -1038,8 +1048,10 @@ jv jv_string_explode(jv j) { @@ -1339,8 +1349,10 @@ jv jv_string_explode(jv j) {
const char* end = i + len; const char* end = i + len;
jv a = jv_array_sized(len); jv a = jv_array_sized(len);
int c; int c;
@ -122,7 +99,7 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
jv_free(j); jv_free(j);
return a; return a;
} }
@@ -1312,10 +1324,13 @@ static void jvp_object_free(jv o) { @@ -1614,10 +1626,13 @@ static void jvp_object_free(jv o) {
} }
} }
@ -137,7 +114,7 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
jv new_object = jvp_object_new(size * 2); jv new_object = jvp_object_new(size * 2);
for (int i=0; i<size; i++) { for (int i=0; i<size; i++) {
struct object_slot* slot = jvp_object_get_slot(object, i); struct object_slot* slot = jvp_object_get_slot(object, i);
@@ -1328,7 +1343,8 @@ static jv jvp_object_rehash(jv object) { @@ -1630,7 +1645,8 @@ static jv jvp_object_rehash(jv object) {
} }
// references are transported, just drop the old table // references are transported, just drop the old table
jv_mem_free(jvp_object_ptr(object)); jv_mem_free(jvp_object_ptr(object));
@ -147,7 +124,7 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
} }
static jv jvp_object_unshare(jv object) { static jv jvp_object_unshare(jv object) {
@@ -1357,27 +1373,32 @@ static jv jvp_object_unshare(jv object) @@ -1659,27 +1675,32 @@ static jv jvp_object_unshare(jv object)
return new_object; return new_object;
} }
@ -184,7 +161,7 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
} }
static int jvp_object_delete(jv* object, jv key) { static int jvp_object_delete(jv* object, jv key) {
@@ -1478,7 +1499,11 @@ jv jv_object_set(jv object, jv key, jv v @@ -1779,7 +1800,11 @@ jv jv_object_set(jv object, jv key, jv v
assert(JVP_HAS_KIND(object, JV_KIND_OBJECT)); assert(JVP_HAS_KIND(object, JV_KIND_OBJECT));
assert(JVP_HAS_KIND(key, JV_KIND_STRING)); assert(JVP_HAS_KIND(key, JV_KIND_STRING));
// copy/free of object, key, value coalesced // copy/free of object, key, value coalesced
@ -197,7 +174,7 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
jv_free(*slot); jv_free(*slot);
*slot = value; *slot = value;
return object; return object;
@@ -1503,6 +1528,7 @@ jv jv_object_merge(jv a, jv b) { @@ -1804,6 +1829,7 @@ jv jv_object_merge(jv a, jv b) {
assert(JVP_HAS_KIND(a, JV_KIND_OBJECT)); assert(JVP_HAS_KIND(a, JV_KIND_OBJECT));
jv_object_foreach(b, k, v) { jv_object_foreach(b, k, v) {
a = jv_object_set(a, k, v); a = jv_object_set(a, k, v);
@ -205,7 +182,7 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
} }
jv_free(b); jv_free(b);
return a; return a;
@@ -1522,6 +1548,7 @@ jv jv_object_merge_recursive(jv a, jv b) @@ -1823,6 +1849,7 @@ jv jv_object_merge_recursive(jv a, jv b)
jv_free(elem); jv_free(elem);
a = jv_object_set(a, k, v); a = jv_object_set(a, k, v);
} }
@ -213,19 +190,10 @@ diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
} }
jv_free(b); jv_free(b);
return a; return a;
@@ -1671,7 +1698,7 @@ int jv_contains(jv a, jv b) { diff -up jq-jq-1.7.1/tests/jq.test.orig jq-jq-1.7.1/tests/jq.test
r = jvp_array_contains(a, b); --- jq-jq-1.7.1/tests/jq.test.orig 2025-06-25 10:07:24.630712938 +0200
} else if (JVP_HAS_KIND(a, JV_KIND_STRING)) { +++ jq-jq-1.7.1/tests/jq.test 2025-06-25 10:10:45.542877328 +0200
int b_len = jv_string_length_bytes(jv_copy(b)); @@ -198,6 +198,10 @@ null
- if (b_len != 0) {
+ if (b_len != 0) {
r = _jq_memmem(jv_string_value(a), jv_string_length_bytes(jv_copy(a)),
jv_string_value(b), b_len) != 0;
} else {
diff -up jq-1.6/tests/jq.test.orig jq-1.6/tests/jq.test
--- jq-1.6/tests/jq.test.orig 2025-06-30 18:14:49.214961567 +0200
+++ jq-1.6/tests/jq.test 2025-06-30 18:15:20.271792714 +0200
@@ -186,6 +186,10 @@ null
[0,1,2] [0,1,2]
[0,5,2] [0,5,2]

View File

@ -1,25 +0,0 @@
diff -up jq-1.6/src/jv.c.iteration jq-1.6/src/jv.c
--- jq-1.6/src/jv.c.iteration 2022-10-21 14:17:26.977551386 +0200
+++ jq-1.6/src/jv.c 2022-10-21 14:18:43.562430867 +0200
@@ -308,6 +308,7 @@ static jv jvp_literal_number_new(const c
n->refcnt = JV_REFCNT_INIT;
n->literal_data = NULL;
decContext *ctx = DEC_CONTEXT();
+ decContextClearStatus(ctx, DEC_Conversion_syntax);
decNumberFromString(&n->num_decimal, literal, ctx);
n->num_double = NAN;
diff -up jq-1.6/tests/optional.test.iteration jq-1.6/tests/optional.test
--- jq-1.6/tests/optional.test.iteration 2022-10-21 14:22:04.191734821 +0200
+++ jq-1.6/tests/optional.test 2022-10-21 14:23:45.820901911 +0200
@@ -17,4 +17,9 @@ strftime("%A, %B %e, %Y")
1435677542.822351
"Tuesday, June 30, 2015"
-
+# iteration must continue after hello
+.[]|tonumber?
+["1", "hello", "3", 4]
+1
+3
+4

141
0002-CVE-2025-48060.patch Normal file
View File

@ -0,0 +1,141 @@
CVE-2025-48060 fix based on:
commit dc849e9bb74a7a164a3ea52f661cc712b1ffbd43
Author: itchyny <itchyny@cybozu.co.jp>
Date: Tue Mar 4 22:13:55 2025 +0900
Improve performance of repeating strings (#3272)
This commit improves the performance of repeating strings, by copying
the result string instead of the string being repeated. Also it adds
an error message when the result string is too long.
and
commit c6e041699d8cd31b97375a2596217aff2cfca85b
Author: itchyny <itchyny@cybozu.co.jp>
Date: Sat May 31 11:46:40 2025 +0900
Fix heap buffer overflow when formatting an empty string
The `jv_string_empty` did not properly null-terminate the string data,
which could lead to a heap buffer overflow. The test case of
GHSA-p7rr-28xf-3m5w (`0[""*0]`) was fixed by the commit dc849e9bb74a,
but another case (`0[[]|implode]`) was still vulnerable. This commit
ensures string data is properly null-terminated, and fixes CVE-2025-48060.
diff -up jq-jq-1.7.1/src/builtin.c.orig jq-jq-1.7.1/src/builtin.c
--- jq-jq-1.7.1/src/builtin.c.orig 2023-12-13 20:20:22.000000000 +0100
+++ jq-jq-1.7.1/src/builtin.c 2025-06-25 10:44:54.924284670 +0200
@@ -369,21 +369,10 @@ jv binop_multiply(jv a, jv b) {
str = b;
num = a;
}
- jv res;
double d = jv_number_value(num);
- if (d < 0 || isnan(d)) {
- res = jv_null();
- } else {
- int n = d;
- size_t alen = jv_string_length_bytes(jv_copy(str));
- res = jv_string_empty(alen * n);
- for (; n > 0; n--) {
- res = jv_string_append_buf(res, jv_string_value(str), alen);
- }
- }
- jv_free(str);
jv_free(num);
- return res;
+ return jv_string_repeat(str,
+ d < 0 || isnan(d) ? -1 : d > INT_MAX ? INT_MAX : (int)d);
} else if (ak == JV_KIND_OBJECT && bk == JV_KIND_OBJECT) {
return jv_object_merge_recursive(a, b);
} else {
diff -up jq-jq-1.7.1/src/jv.c.orig jq-jq-1.7.1/src/jv.c
--- jq-jq-1.7.1/src/jv.c.orig 2025-06-25 10:53:50.314332900 +0200
+++ jq-jq-1.7.1/src/jv.c 2025-06-25 10:51:23.208740329 +0200
@@ -1125,6 +1125,7 @@ static jv jvp_string_empty_new(uint32_t
jvp_string* s = jvp_string_alloc(length);
s->length_hashed = 0;
memset(s->data, 0, length);
+ s->data[length] = 0;
jv r = {JVP_FLAGS_STRING, 0, 0, 0, {&s->refcnt}};
return r;
}
@@ -1307,6 +1308,32 @@ jv jv_string_indexes(jv j, jv k) {
return a;
}
+jv jv_string_repeat(jv j, int n) {
+ assert(JVP_HAS_KIND(j, JV_KIND_STRING));
+ if (n < 0) {
+ jv_free(j);
+ return jv_null();
+ }
+ int len = jv_string_length_bytes(jv_copy(j));
+ int64_t res_len = (int64_t)len * n;
+ if (res_len >= INT_MAX) {
+ jv_free(j);
+ return jv_invalid_with_msg(jv_string("Repeat string result too long"));
+ }
+ if (res_len == 0) {
+ jv_free(j);
+ return jv_string("");
+ }
+ jv res = jv_string_empty(res_len);
+ res = jvp_string_append(res, jv_string_value(j), len);
+ for (int curr = len, grow; curr < res_len; curr += grow) {
+ grow = MIN(res_len - curr, curr);
+ res = jvp_string_append(res, jv_string_value(res), grow);
+ }
+ jv_free(j);
+ return res;
+}
+
jv jv_string_split(jv j, jv sep) {
assert(JVP_HAS_KIND(j, JV_KIND_STRING));
assert(JVP_HAS_KIND(sep, JV_KIND_STRING));
diff -up jq-jq-1.7.1/src/jv.h.orig jq-jq-1.7.1/src/jv.h
--- jq-jq-1.7.1/src/jv.h.orig 2023-12-13 20:20:22.000000000 +0100
+++ jq-jq-1.7.1/src/jv.h 2025-06-25 10:44:54.925242109 +0200
@@ -131,6 +131,7 @@ jv jv_string_fmt(const char*, ...) JV_PR
jv jv_string_append_codepoint(jv a, uint32_t c);
jv jv_string_append_buf(jv a, const char* buf, int len);
jv jv_string_append_str(jv a, const char* str);
+jv jv_string_repeat(jv j, int n);
jv jv_string_split(jv j, jv sep);
jv jv_string_explode(jv j);
jv jv_string_implode(jv j);
diff -up jq-jq-1.7.1/tests/jq.test.orig jq-jq-1.7.1/tests/jq.test
--- jq-jq-1.7.1/tests/jq.test.orig 2025-06-25 10:53:02.390073835 +0200
+++ jq-jq-1.7.1/tests/jq.test 2025-06-25 10:51:23.209350316 +0200
@@ -1369,6 +1369,18 @@ indices(", ")
"abc"
[null,null]
+. * 100000 | [.[:10],.[-10:]]
+"abc"
+["abcabcabca","cabcabcabc"]
+
+. * 1000000000
+""
+""
+
+try (. * 1000000000) catch .
+"abc"
+"Repeat string result too long"
+
[.[] / ","]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a"," bc"," def"," ghij"," jklmn"," a","b"," c","d"," e","f"],["a","b","c","d"," e","f","g","h"]]
@@ -2030,6 +2042,10 @@ map(try implode catch .)
[123,["a"],[nan]]
["implode input must be an array","string (\"a\") can't be imploded, unicode codepoint needs to be numeric","number (null) can't be imploded, unicode codepoint needs to be numeric"]
+try 0[implode] catch .
+[]
+"Cannot index number with string \"\""
+
# walk
walk(.)
{"x":0}

View File

@ -1,851 +0,0 @@
man.test from commit 50a7022ea68fb37faefdcd7a35661df72fbfd655
diff --git a/tests/man.test b/tests/man.test
new file mode 100644
index 0000000..2a49eff
--- /dev/null
+++ b/tests/man.test
@@ -0,0 +1,843 @@
+.
+"Hello, world!"
+"Hello, world!"
+
+.foo
+{"foo": 42, "bar": "less interesting data"}
+42
+
+.foo
+{"notfoo": true, "alsonotfoo": false}
+null
+
+.["foo"]
+{"foo": 42}
+42
+
+.foo?
+{"foo": 42, "bar": "less interesting data"}
+42
+
+.foo?
+{"notfoo": true, "alsonotfoo": false}
+null
+
+.["foo"]?
+{"foo": 42}
+42
+
+[.foo?]
+[1,2]
+[]
+
+.[0]
+[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
+{"name":"JSON", "good":true}
+
+.[2]
+[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
+null
+
+.[-2]
+[1,2,3]
+2
+
+.[2:4]
+["a","b","c","d","e"]
+["c", "d"]
+
+.[2:4]
+"abcdefghi"
+"cd"
+
+.[:3]
+["a","b","c","d","e"]
+["a", "b", "c"]
+
+.[-2:]
+["a","b","c","d","e"]
+["d", "e"]
+
+.[]
+[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
+{"name":"JSON", "good":true}
+{"name":"XML", "good":false}
+
+.[]
+[]
+
+.[]
+{"a": 1, "b": 1}
+1
+1
+
+.foo, .bar
+{"foo": 42, "bar": "something else", "baz": true}
+42
+"something else"
+
+.user, .projects[]
+{"user":"stedolan", "projects": ["jq", "wikiflow"]}
+"stedolan"
+"jq"
+"wikiflow"
+
+.[4,2]
+["a","b","c","d","e"]
+"e"
+"c"
+
+.[] | .name
+[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]
+"JSON"
+"XML"
+
+(. + 2) * 5
+1
+15
+
+[.user, .projects[]]
+{"user":"stedolan", "projects": ["jq", "wikiflow"]}
+["stedolan", "jq", "wikiflow"]
+
+[ .[] | . * 2]
+[1, 2, 3]
+[2, 4, 6]
+
+{user, title: .titles[]}
+{"user":"stedolan","titles":["JQ Primer", "More JQ"]}
+{"user":"stedolan", "title": "JQ Primer"}
+{"user":"stedolan", "title": "More JQ"}
+
+{(.user): .titles}
+{"user":"stedolan","titles":["JQ Primer", "More JQ"]}
+{"stedolan": ["JQ Primer", "More JQ"]}
+
+..|.a?
+[[{"a":1}]]
+1
+
+.a + 1
+{"a": 7}
+8
+
+.a + .b
+{"a": [1,2], "b": [3,4]}
+[1,2,3,4]
+
+.a + null
+{"a": 1}
+1
+
+.a + 1
+{}
+1
+
+{a: 1} + {b: 2} + {c: 3} + {a: 42}
+null
+{"a": 42, "b": 2, "c": 3}
+
+4 - .a
+{"a":3}
+1
+
+. - ["xml", "yaml"]
+["xml", "yaml", "json"]
+["json"]
+
+10 / . * 3
+5
+6
+
+. / ", "
+"a, b,c,d, e"
+["a","b,c,d","e"]
+
+{"k": {"a": 1, "b": 2}} * {"k": {"a": 0,"c": 3}}
+null
+{"k": {"a": 0, "b": 2, "c": 3}}
+
+.[] | (1 / .)?
+[1,0,-1]
+1
+-1
+
+.[] | length
+[[1,2], "string", {"a":2}, null]
+2
+6
+1
+0
+
+utf8bytelength
+"\u03bc"
+2
+
+keys
+{"abc": 1, "abcd": 2, "Foo": 3}
+["Foo", "abc", "abcd"]
+
+keys
+[42,3,35]
+[0,1,2]
+
+map(has("foo"))
+[{"foo": 42}, {}]
+[true, false]
+
+map(has(2))
+[[0,1], ["a","b","c"]]
+[false, true]
+
+.[] | in({"foo": 42})
+["foo", "bar"]
+true
+false
+
+map(in([0,1]))
+[2, 0]
+[false, true]
+
+map(.+1)
+[1,2,3]
+[2,3,4]
+
+map_values(.+1)
+{"a": 1, "b": 2, "c": 3}
+{"a": 2, "b": 3, "c": 4}
+
+path(.a[0].b)
+null
+["a",0,"b"]
+
+[path(..)]
+{"a":[{"b":1}]}
+[[],["a"],["a",0],["a",0,"b"]]
+
+del(.foo)
+{"foo": 42, "bar": 9001, "baz": 42}
+{"bar": 9001, "baz": 42}
+
+del(.[1, 2])
+["foo", "bar", "baz"]
+["foo"]
+
+getpath(["a","b"])
+null
+null
+
+[getpath(["a","b"], ["a","c"])]
+{"a":{"b":0, "c":1}}
+[0, 1]
+
+setpath(["a","b"]; 1)
+null
+{"a": {"b": 1}}
+
+setpath(["a","b"]; 1)
+{"a":{"b":0}}
+{"a": {"b": 1}}
+
+setpath([0,"a"]; 1)
+null
+[{"a":1}]
+
+delpaths([["a","b"]])
+{"a":{"b":1},"x":{"y":2}}
+{"a":{},"x":{"y":2}}
+
+to_entries
+{"a": 1, "b": 2}
+[{"key":"a", "value":1}, {"key":"b", "value":2}]
+
+from_entries
+[{"key":"a", "value":1}, {"key":"b", "value":2}]
+{"a": 1, "b": 2}
+
+with_entries(.key |= "KEY_" + .)
+{"a": 1, "b": 2}
+{"KEY_a": 1, "KEY_b": 2}
+
+map(select(. >= 2))
+[1,5,3,0,7]
+[5,3,7]
+
+.[] | select(.id == "second")
+[{"id": "first", "val": 1}, {"id": "second", "val": 2}]
+{"id": "second", "val": 2}
+
+.[]|numbers
+[[],{},1,"foo",null,true,false]
+1
+
+1, empty, 2
+null
+1
+2
+
+[1,2,empty,3]
+null
+[1,2,3]
+
+try error("\($__loc__)") catch .
+null
+"{\"file\":\"<top-level>\",\"line\":1}"
+
+[paths]
+[1,[[],{"a":2}]]
+[[0],[1],[1,0],[1,1],[1,1,"a"]]
+
+[paths(scalars)]
+[1,[[],{"a":2}]]
+[[0],[1,1,"a"]]
+
+add
+["a","b","c"]
+"abc"
+
+add
+[1, 2, 3]
+6
+
+add
+[]
+null
+
+any
+[true, false]
+true
+
+any
+[false, false]
+false
+
+any
+[]
+false
+
+all
+[true, false]
+false
+
+all
+[true, true]
+true
+
+all
+[]
+true
+
+flatten
+[1, [2], [[3]]]
+[1, 2, 3]
+
+flatten(1)
+[1, [2], [[3]]]
+[1, 2, [3]]
+
+flatten
+[[]]
+[]
+
+flatten
+[{"foo": "bar"}, [{"foo": "baz"}]]
+[{"foo": "bar"}, {"foo": "baz"}]
+
+range(2;4)
+null
+2
+3
+
+[range(2;4)]
+null
+[2,3]
+
+[range(4)]
+null
+[0,1,2,3]
+
+[range(0;10;3)]
+null
+[0,3,6,9]
+
+[range(0;10;-1)]
+null
+[]
+
+[range(0;-5;-1)]
+null
+[0,-1,-2,-3,-4]
+
+floor
+3.14159
+3
+
+sqrt
+9
+3
+
+.[] | tonumber
+[1, "1"]
+1
+1
+
+.[] | tostring
+[1, "1", [1]]
+"1"
+"1"
+"[1]"
+
+map(type)
+[0, false, [], {}, null, "hello"]
+["number", "boolean", "array", "object", "null", "string"]
+
+.[] | (infinite * .) < 0
+[-1, 1]
+true
+false
+
+infinite, nan | type
+null
+"number"
+"number"
+
+sort
+[8,3,null,6]
+[null,3,6,8]
+
+sort_by(.foo)
+[{"foo":4, "bar":10}, {"foo":3, "bar":100}, {"foo":2, "bar":1}]
+[{"foo":2, "bar":1}, {"foo":3, "bar":100}, {"foo":4, "bar":10}]
+
+group_by(.foo)
+[{"foo":1, "bar":10}, {"foo":3, "bar":100}, {"foo":1, "bar":1}]
+[[{"foo":1, "bar":10}, {"foo":1, "bar":1}], [{"foo":3, "bar":100}]]
+
+min
+[5,4,2,7]
+2
+
+max_by(.foo)
+[{"foo":1, "bar":14}, {"foo":2, "bar":3}]
+{"foo":2, "bar":3}
+
+unique
+[1,2,5,3,5,3,1,3]
+[1,2,3,5]
+
+unique_by(.foo)
+[{"foo": 1, "bar": 2}, {"foo": 1, "bar": 3}, {"foo": 4, "bar": 5}]
+[{"foo": 1, "bar": 2}, {"foo": 4, "bar": 5}]
+
+unique_by(length)
+["chunky", "bacon", "kitten", "cicada", "asparagus"]
+["bacon", "chunky", "asparagus"]
+
+reverse
+[1,2,3,4]
+[4,3,2,1]
+
+contains("bar")
+"foobar"
+true
+
+contains(["baz", "bar"])
+["foobar", "foobaz", "blarp"]
+true
+
+contains(["bazzzzz", "bar"])
+["foobar", "foobaz", "blarp"]
+false
+
+contains({foo: 12, bar: [{barp: 12}]})
+{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}
+true
+
+contains({foo: 12, bar: [{barp: 15}]})
+{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}
+false
+
+indices(", ")
+"a,b, cd, efg, hijk"
+[3,7,12]
+
+indices(1)
+[0,1,2,1,3,1,4]
+[1,3,5]
+
+indices([1,2])
+[0,1,2,3,1,4,2,5,1,2,6,7]
+[1,8]
+
+index(", ")
+"a,b, cd, efg, hijk"
+3
+
+rindex(", ")
+"a,b, cd, efg, hijk"
+12
+
+inside("foobar")
+"bar"
+true
+
+inside(["foobar", "foobaz", "blarp"])
+["baz", "bar"]
+true
+
+inside(["foobar", "foobaz", "blarp"])
+["bazzzzz", "bar"]
+false
+
+inside({"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]})
+{"foo": 12, "bar": [{"barp": 12}]}
+true
+
+inside({"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]})
+{"foo": 12, "bar": [{"barp": 15}]}
+false
+
+[.[]|startswith("foo")]
+["fo", "foo", "barfoo", "foobar", "barfoob"]
+[false, true, false, true, false]
+
+[.[]|endswith("foo")]
+["foobar", "barfoo"]
+[false, true]
+
+combinations
+[[1,2], [3, 4]]
+[1, 3]
+[1, 4]
+[2, 3]
+[2, 4]
+
+combinations(2)
+[0, 1]
+[0, 0]
+[0, 1]
+[1, 0]
+[1, 1]
+
+[.[]|ltrimstr("foo")]
+["fo", "foo", "barfoo", "foobar", "afoo"]
+["fo","","barfoo","bar","afoo"]
+
+[.[]|rtrimstr("foo")]
+["fo", "foo", "barfoo", "foobar", "foob"]
+["fo","","bar","foobar","foob"]
+
+explode
+"foobar"
+[102,111,111,98,97,114]
+
+implode
+[65, 66, 67]
+"ABC"
+
+split(", ")
+"a, b,c,d, e, "
+["a","b,c,d","e",""]
+
+join(", ")
+["a","b,c,d","e"]
+"a, b,c,d, e"
+
+join(" ")
+["a",1,2.3,true,null,false]
+"a 1 2.3 true false"
+
+[while(.<100; .*2)]
+1
+[1,2,4,8,16,32,64]
+
+[.,1]|until(.[0] < 1; [.[0] - 1, .[1] * .[0]])|.[1]
+4
+24
+
+recurse(.foo[])
+{"foo":[{"foo": []}, {"foo":[{"foo":[]}]}]}
+{"foo":[{"foo":[]},{"foo":[{"foo":[]}]}]}
+{"foo":[]}
+{"foo":[{"foo":[]}]}
+{"foo":[]}
+
+recurse
+{"a":0,"b":[1]}
+{"a":0,"b":[1]}
+0
+[1]
+1
+
+recurse(. * .; . < 20)
+2
+2
+4
+16
+
+walk(if type == "array" then sort else . end)
+[[4, 1, 7], [8, 5, 2], [3, 6, 9]]
+[[1,4,7],[2,5,8],[3,6,9]]
+
+walk( if type == "object" then with_entries( .key |= sub( "^_+"; "") ) else . end )
+[ { "_a": { "__b": 2 } } ]
+[{"a":{"b":2}}]
+
+$ENV.PAGER
+null
+"less"
+
+env.PAGER
+null
+"less"
+
+transpose
+[[1], [2,3]]
+[[1,2],[null,3]]
+
+bsearch(0)
+[0,1]
+0
+
+bsearch(0)
+[1,2,3]
+-1
+
+bsearch(4) as $ix | if $ix < 0 then .[-(1+$ix)] = 4 else . end
+[1,2,3]
+[1,2,3,4]
+
+"The input was \(.), which is one less than \(.+1)"
+42
+"The input was 42, which is one less than 43"
+
+[.[]|tostring]
+[1, "foo", ["foo"]]
+["1","foo","[\"foo\"]"]
+
+[.[]|tojson]
+[1, "foo", ["foo"]]
+["1","\"foo\"","[\"foo\"]"]
+
+[.[]|tojson|fromjson]
+[1, "foo", ["foo"]]
+[1,"foo",["foo"]]
+
+@html
+"This works if x < y"
+"This works if x &lt; y"
+
+@sh "echo \(.)"
+"O'Hara's Ale"
+"echo 'O'\\''Hara'\\''s Ale'"
+
+@base64
+"This is a message"
+"VGhpcyBpcyBhIG1lc3NhZ2U="
+
+@base64d
+"VGhpcyBpcyBhIG1lc3NhZ2U="
+"This is a message"
+
+fromdate
+"2015-03-05T23:51:47Z"
+1425599507
+
+strptime("%Y-%m-%dT%H:%M:%SZ")
+"2015-03-05T23:51:47Z"
+[2015,2,5,23,51,47,4,63]
+
+strptime("%Y-%m-%dT%H:%M:%SZ")|mktime
+"2015-03-05T23:51:47Z"
+1425599507
+
+.[] == 1
+[1, 1.0, "1", "banana"]
+true
+true
+false
+false
+
+if . == 0 then "zero" elif . == 1 then "one" else "many" end
+2
+"many"
+
+. < 5
+2
+true
+
+42 and "a string"
+null
+true
+
+(true, false) or false
+null
+true
+false
+
+(true, true) and (true, false)
+null
+true
+false
+true
+false
+
+[true, false | not]
+null
+[false, true]
+
+.foo // 42
+{"foo": 19}
+19
+
+.foo // 42
+{}
+42
+
+try .a catch ". is not an object"
+true
+". is not an object"
+
+[.[]|try .a]
+[{}, true, {"a":1}]
+[null, 1]
+
+try error("some exception") catch .
+true
+"some exception"
+
+[.[]|(.a)?]
+[{}, true, {"a":1}]
+[null, 1]
+
+test("foo")
+"foo"
+true
+
+.[] | test("a b c # spaces are ignored"; "ix")
+["xabcd", "ABC"]
+true
+true
+
+match("(abc)+"; "g")
+"abc abc"
+{"offset": 0, "length": 3, "string": "abc", "captures": [{"offset": 0, "length": 3, "string": "abc", "name": null}]}
+{"offset": 4, "length": 3, "string": "abc", "captures": [{"offset": 4, "length": 3, "string": "abc", "name": null}]}
+
+match("foo")
+"foo bar foo"
+{"offset": 0, "length": 3, "string": "foo", "captures": []}
+
+match(["foo", "ig"])
+"foo bar FOO"
+{"offset": 0, "length": 3, "string": "foo", "captures": []}
+{"offset": 8, "length": 3, "string": "FOO", "captures": []}
+
+match("foo (?<bar123>bar)? foo"; "ig")
+"foo bar foo foo foo"
+{"offset": 0, "length": 11, "string": "foo bar foo", "captures": [{"offset": 4, "length": 3, "string": "bar", "name": "bar123"}]}
+{"offset": 12, "length": 8, "string": "foo foo", "captures": [{"offset": -1, "length": 0, "string": null, "name": "bar123"}]}
+
+[ match("."; "g")] | length
+"abc"
+3
+
+capture("(?<a>[a-z]+)-(?<n>[0-9]+)")
+"xyzzy-14"
+{ "a": "xyzzy", "n": "14" }
+
+.bar as $x | .foo | . + $x
+{"foo":10, "bar":200}
+210
+
+. as $i|[(.*2|. as $i| $i), $i]
+5
+[10,5]
+
+. as [$a, $b, {c: $c}] | $a + $b + $c
+[2, 3, {"c": 4, "d": 5}]
+9
+
+.[] as [$a, $b] | {a: $a, b: $b}
+[[0], [0, 1], [2, 1, 0]]
+{"a":0,"b":null}
+{"a":0,"b":1}
+{"a":2,"b":1}
+
+.[] as {$a, $b, c: {$d, $e}} ?// {$a, $b, c: [{$d, $e}]} | {$a, $b, $d, $e}
+[{"a": 1, "b": 2, "c": {"d": 3, "e": 4}}, {"a": 1, "b": 2, "c": [{"d": 3, "e": 4}]}]
+{"a":1,"b":2,"d":3,"e":4}
+{"a":1,"b":2,"d":3,"e":4}
+
+.[] as {$a, $b, c: {$d}} ?// {$a, $b, c: [{$e}]} | {$a, $b, $d, $e}
+[{"a": 1, "b": 2, "c": {"d": 3, "e": 4}}, {"a": 1, "b": 2, "c": [{"d": 3, "e": 4}]}]
+{"a":1,"b":2,"d":3,"e":null}
+{"a":1,"b":2,"d":null,"e":4}
+
+.[] as [$a] ?// [$b] | if $a != null then error("err: \($a)") else {$a,$b} end
+[[3]]
+{"a":null,"b":3}
+
+def addvalue(f): . + [f]; map(addvalue(.[0]))
+[[1,2],[10,20]]
+[[1,2,1], [10,20,10]]
+
+def addvalue(f): f as $x | map(. + $x); addvalue(.[0])
+[[1,2],[10,20]]
+[[1,2,1,2], [10,20,1,2]]
+
+reduce .[] as $item (0; . + $item)
+[10,2,5,3]
+20
+
+isempty(empty)
+null
+true
+
+[limit(3;.[])]
+[0,1,2,3,4,5,6,7,8,9]
+[0,1,2]
+
+[first(range(.)), last(range(.)), nth(./2; range(.))]
+10
+[0,9,5]
+
+[range(.)]|[first, last, nth(5)]
+10
+[0,9,5]
+
+[foreach .[] as $item ([[],[]]; if $item == null then [[],.[0]] else [(.[0] + [$item]),[]] end; if $item == null then .[1] else empty end)]
+[1,2,3,4,null,"a","b",null]
+[[1,2,3,4],["a","b"]]
+
+def range(init; upto; by): def _range: if (by > 0 and . < upto) or (by < 0 and . > upto) then ., ((.+by)|_range) else . end; if by == 0 then init else init|_range end | select((by > 0 and . < upto) or (by < 0 and . > upto)); range(0; 10; 3)
+null
+0
+3
+6
+9
+
+def while(cond; update): def _while: if cond then ., (update | _while) else empty end; _while; [while(.<100; .*2)]
+1
+[1,2,4,8,16,32,64]
+
+[1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]])]
+1
+[[[0],2],[[0]]]
+
+fromstream(1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]]))
+null
+[2]
+
+. as $dot|fromstream($dot|tostream)|.==$dot
+[0,[1,{"a":1},{"b":2}]]
+true
+
+(..|select(type=="boolean")) |= if . then 1 else 0 end
+[true,false,[5,true,[true,[false]],false]]
+[1,0,[5,1,[1,[0]],0]]
+
+.foo += 1
+{"foo": 42}
+{"foo": 43}
+

View File

@ -1,244 +0,0 @@
commit fead9669cb67badb22789d3ed1888779ed85c679
Author: Tomas Halman <thalman@redhat.com>
Date: Thu Mar 9 11:34:44 2023 +0100
Test that jq works in threads
This patch implements test that searches a key in simple
json in pthread.
diff -up jq-1.6/src/jq_test.c.orig jq-1.6/src/jq_test.c
--- jq-1.6/src/jq_test.c.orig 2023-03-09 14:02:16.980062057 +0100
+++ jq-1.6/src/jq_test.c 2023-03-09 14:03:38.347017032 +0100
@@ -2,12 +2,17 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
#include "jv.h"
#include "jq.h"
static void jv_test();
static void run_jq_tests(jv, int, FILE *, int, int);
-
+#ifdef HAVE_PTHREAD
+static void run_jq_pthread_tests();
+#endif
int jq_testsuite(jv libdirs, int verbose, int argc, char* argv[]) {
FILE *testdata = stdin;
@@ -32,6 +37,9 @@ int jq_testsuite(jv libdirs, int verbose
}
}
run_jq_tests(libdirs, verbose, testdata, skip, take);
+#ifdef HAVE_PTHREAD
+ run_jq_pthread_tests();
+#endif
return 0;
}
@@ -105,7 +113,7 @@ static void run_jq_tests(jv lib_dirs, in
if (buf[0] == '\n' || (buf[0] == '\r' && buf[1] == '\n'))
break;
}
-
+
must_fail = 0;
check_msg = 0;
@@ -229,7 +237,7 @@ static void run_jq_tests(jv lib_dirs, in
total_skipped = tests_to_skip - skip;
}
- printf("%d of %d tests passed (%d malformed, %d skipped)\n",
+ printf("%d of %d tests passed (%d malformed, %d skipped)\n",
passed, tests, invalid, total_skipped);
if (skip > 0) {
@@ -241,6 +249,88 @@ static void run_jq_tests(jv lib_dirs, in
}
+/// pthread regression test
+#ifdef HAVE_PTHREAD
+#define NUMBER_OF_THREADS 3
+struct test_pthread_data {
+ int result;
+};
+
+static int test_pthread_jq_parse(jq_state *jq, struct jv_parser *parser)
+{
+ int rv = 0;
+ jv value;
+
+ value = jv_parser_next(parser);
+ while (jv_is_valid(value)) {
+ jq_start(jq, value, 0);
+ jv result = jq_next(jq);
+
+ while (jv_is_valid(result)) {
+ jv_free(result);
+ result = jq_next(jq);
+ }
+ jv_free(result);
+ value = jv_parser_next(parser);
+ }
+ jv_free(value);
+ return rv;
+}
+
+static void *test_pthread_run(void *ptr) {
+ int rv;
+ jq_state *jq;
+ const char *prg = ".data";
+ const char *buf = "{ \"data\": 1 }";
+ struct test_pthread_data *data = ptr;
+
+ jq = jq_init();
+ if (jq_compile(jq, prg) == 0) {
+ jq_teardown(&jq);
+ return NULL;
+ }
+
+ struct jv_parser *parser = jv_parser_new(0);
+ jv_parser_set_buf(parser, buf, strlen(buf), 0);
+ rv = test_pthread_jq_parse(jq, parser);
+
+ data->result = rv;
+
+ jv_parser_free(parser);
+ jq_teardown(&jq);
+ return NULL;
+}
+
+static void run_jq_pthread_tests() {
+ pthread_t threads[NUMBER_OF_THREADS];
+ struct test_pthread_data data[NUMBER_OF_THREADS];
+ int createerror;
+ int a;
+
+ memset(&threads, 0, sizeof(threads));
+ memset(&data, 0, sizeof(data));
+
+ // Create all threads
+ for (a = 0; a < NUMBER_OF_THREADS; ++a) {
+ createerror = pthread_create(&threads[a], NULL, test_pthread_run, &data[a]);
+ assert(createerror == 0);
+ }
+
+ // wait for all threads
+ for(a = 0; a < NUMBER_OF_THREADS; ++a) {
+ if (threads[a] != 0) {
+ pthread_join(threads[a], NULL);
+ }
+ }
+
+ // check results
+ for(a = 0; a < NUMBER_OF_THREADS; ++a) {
+ assert(data[a].result == 0);
+ }
+}
+#endif // HAVE_PTHREAD
+
+
static void jv_test() {
/// JSON parser regression tests
{
commit f05c5bb521f404592b137e02a1b8abd50da87ca3
Author: Tomas Halman <thalman@redhat.com>
Date: Wed Mar 1 20:07:28 2023 +0100
Fix segmentation fault when using jq in threads
In previous code nomem_handler in jv_alloc.c is called only once
and therefore the structure is not initialized for second and
following threads.
This leads to segmentation fault in multi-threading environment.
This patch moves initialization of nomem_handler out of the
pthread_once call.
diff -up jq-1.6/src/jv_alloc.c.orig jq-1.6/src/jv_alloc.c
--- jq-1.6/src/jv_alloc.c.orig 2018-11-02 02:49:29.000000000 +0100
+++ jq-1.6/src/jv_alloc.c 2023-03-09 14:13:47.810177037 +0100
@@ -45,9 +45,11 @@ static void memory_exhausted() {
#ifdef HAVE_PTHREAD_KEY_CREATE
#include <pthread.h>
-pthread_key_t nomem_handler_key;
-pthread_once_t mem_once = PTHREAD_ONCE_INIT;
+static pthread_key_t nomem_handler_key;
+static pthread_once_t mem_once = PTHREAD_ONCE_INIT;
+/* tsd_fini is called on application exit */
+/* it clears the nomem_handler allocated in the main thread */
static void tsd_fini(void) {
struct nomem_handler *nomem_handler;
nomem_handler = pthread_getspecific(nomem_handler_key);
@@ -57,30 +59,45 @@ static void tsd_fini(void) {
}
}
+/* The tsd_fini_thread is a destructor set by calling */
+/* pthread_key_create(&nomem_handler_key, tsd_fini_thread) */
+/* It is called when thread ends */
+static void tsd_fini_thread(void *nomem_handler) {
+ free(nomem_handler);
+}
+
static void tsd_init(void) {
- if (pthread_key_create(&nomem_handler_key, NULL) != 0) {
- fprintf(stderr, "error: cannot create thread specific key");
+ if (pthread_key_create(&nomem_handler_key, tsd_fini_thread) != 0) {
+ fprintf(stderr, "jq: error: cannot create thread specific key");
abort();
}
if (atexit(tsd_fini) != 0) {
- fprintf(stderr, "error: cannot set an exit handler");
+ fprintf(stderr, "jq: error: cannot set an exit handler");
abort();
}
- struct nomem_handler *nomem_handler = calloc(1, sizeof(struct nomem_handler));
- if (pthread_setspecific(nomem_handler_key, nomem_handler) != 0) {
- fprintf(stderr, "error: cannot set thread specific data");
- abort();
+}
+
+static void tsd_init_nomem_handler(void)
+{
+ if (pthread_getspecific(nomem_handler_key) == NULL) {
+ struct nomem_handler *nomem_handler = calloc(1, sizeof(struct nomem_handler));
+ if (pthread_setspecific(nomem_handler_key, nomem_handler) != 0) {
+ fprintf(stderr, "jq: error: cannot set thread specific data");
+ abort();
+ }
}
}
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
pthread_once(&mem_once, tsd_init); // cannot fail
+ tsd_init_nomem_handler();
+
struct nomem_handler *nomem_handler;
nomem_handler = pthread_getspecific(nomem_handler_key);
if (nomem_handler == NULL) {
handler(data);
- fprintf(stderr, "error: cannot allocate memory\n");
+ fprintf(stderr, "jq: error: cannot allocate memory\n");
abort();
}
nomem_handler->handler = handler;
@@ -91,6 +108,8 @@ static void memory_exhausted() {
struct nomem_handler *nomem_handler;
pthread_once(&mem_once, tsd_init);
+ tsd_init_nomem_handler();
+
nomem_handler = pthread_getspecific(nomem_handler_key);
if (nomem_handler)
nomem_handler->handler(nomem_handler->data); // Maybe handler() will longjmp() to safety

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +0,0 @@
diff -up jq-1.6/src/jq_test.c.orig jq-1.6/src/jq_test.c
--- jq-1.6/src/jq_test.c.orig 2024-05-03 11:47:47.403617188 +0200
+++ jq-1.6/src/jq_test.c 2024-05-03 11:48:46.569675199 +0200
@@ -16,6 +16,7 @@ static void run_jq_pthread_tests();
int jq_testsuite(jv libdirs, int verbose, int argc, char* argv[]) {
FILE *testdata = stdin;
+ const char *testdata_filename = NULL;
int skip = -1;
int take = -1;
jv_test();
@@ -28,18 +29,24 @@ int jq_testsuite(jv libdirs, int verbose
take = atoi(argv[i+1]);
i++;
} else {
- testdata = fopen(argv[i], "r");
- if (!testdata) {
- perror("fopen");
- exit(1);
- }
+ testdata_filename = argv[i];
}
}
}
+ if (testdata_filename) {
+ testdata = fopen(testdata_filename, "r");
+ if (!testdata) {
+ perror("fopen");
+ exit(1);
+ }
+ }
run_jq_tests(libdirs, verbose, testdata, skip, take);
#ifdef HAVE_PTHREAD
run_jq_pthread_tests();
#endif
+ if (testdata_filename) {
+ fclose(testdata);
+ }
return 0;
}
diff -up jq-1.6/src/locfile.c.orig jq-1.6/src/locfile.c
--- jq-1.6/src/locfile.c.orig 2018-11-02 02:49:29.000000000 +0100
+++ jq-1.6/src/locfile.c 2024-05-03 11:15:46.562476303 +0200
@@ -72,6 +72,7 @@ void locfile_locate(struct locfile* l, l
}
jv m1 = jv_string_vfmt(fmt, fmtargs);
+ va_end(fmtargs);
if (!jv_is_valid(m1)) {
jq_report_error(l->jq, m1);
return;

View File

@ -1,111 +0,0 @@
diff -up jq-1.6/src/builtin.c.orig jq-1.6/src/builtin.c
--- jq-1.6/src/builtin.c.orig 2025-06-30 19:07:06.250825334 +0200
+++ jq-1.6/src/builtin.c 2025-06-30 19:08:51.635668449 +0200
@@ -317,19 +317,10 @@ static jv f_multiply(jq_state *jq, jv in
str = b;
num = a;
}
- int n;
- size_t alen = jv_string_length_bytes(jv_copy(str));
- jv res = str;
-
- for (n = jv_number_value(num) - 1; n > 0; n--)
- res = jv_string_append_buf(res, jv_string_value(str), alen);
-
+ double d = jv_number_value(num);
jv_free(num);
- if (n < 0) {
- jv_free(str);
- return jv_null();
- }
- return res;
+ return jv_string_repeat(str,
+ d < 0 || isnan(d) ? -1 : d > INT_MAX ? INT_MAX : (int)d);
} else if (ak == JV_KIND_OBJECT && bk == JV_KIND_OBJECT) {
return jv_object_merge_recursive(a, b);
} else {
diff -up jq-1.6/src/jv.c.orig jq-1.6/src/jv.c
--- jq-1.6/src/jv.c.orig 2025-06-30 19:06:08.660648842 +0200
+++ jq-1.6/src/jv.c 2025-06-30 19:07:06.251424952 +0200
@@ -828,6 +828,7 @@ static jv jvp_string_empty_new(uint32_t
jvp_string* s = jvp_string_alloc(length);
s->length_hashed = 0;
memset(s->data, 0, length);
+ s->data[length] = 0;
jv r = {JVP_FLAGS_STRING, 0, 0, 0, {&s->refcnt}};
return r;
}
@@ -1006,6 +1007,32 @@ jv jv_string_indexes(jv j, jv k) {
return a;
}
+jv jv_string_repeat(jv j, int n) {
+ assert(JVP_HAS_KIND(j, JV_KIND_STRING));
+ if (n < 0) {
+ jv_free(j);
+ return jv_null();
+ }
+ int len = jv_string_length_bytes(jv_copy(j));
+ int64_t res_len = (int64_t)len * n;
+ if (res_len >= INT_MAX) {
+ jv_free(j);
+ return jv_invalid_with_msg(jv_string("Repeat string result too long"));
+ }
+ if (res_len == 0) {
+ jv_free(j);
+ return jv_string("");
+ }
+ jv res = jv_string_empty(res_len);
+ res = jvp_string_append(res, jv_string_value(j), len);
+ for (int curr = len, grow; curr < res_len; curr += grow) {
+ grow = MIN(res_len - curr, curr);
+ res = jvp_string_append(res, jv_string_value(res), grow);
+ }
+ jv_free(j);
+ return res;
+}
+
jv jv_string_split(jv j, jv sep) {
assert(JVP_HAS_KIND(j, JV_KIND_STRING));
assert(JVP_HAS_KIND(sep, JV_KIND_STRING));
diff -up jq-1.6/src/jv.h.orig jq-1.6/src/jv.h
--- jq-1.6/src/jv.h.orig 2025-06-30 19:06:08.614632776 +0200
+++ jq-1.6/src/jv.h 2025-06-30 19:07:06.251840524 +0200
@@ -120,6 +120,7 @@ jv jv_string_fmt(const char*, ...) JV_PR
jv jv_string_append_codepoint(jv a, uint32_t c);
jv jv_string_append_buf(jv a, const char* buf, int len);
jv jv_string_append_str(jv a, const char* str);
+jv jv_string_repeat(jv j, int n);
jv jv_string_split(jv j, jv sep);
jv jv_string_explode(jv j);
jv jv_string_implode(jv j);
diff -up jq-1.6/tests/jq.test.orig jq-1.6/tests/jq.test
--- jq-1.6/tests/jq.test.orig 2025-06-30 19:06:08.661007480 +0200
+++ jq-1.6/tests/jq.test 2025-06-30 19:09:33.221816670 +0200
@@ -1169,6 +1169,18 @@ indices(", ")
["a", "ab", "abc"]
["aaa", "ababab", "abcabcabc"]
+. * 100000 | [.[:10],.[-10:]]
+"abc"
+["abcabcabca","cabcabcabc"]
+
+. * 1000000000
+""
+""
+
+try (. * 1000000000) catch .
+"abc"
+"Repeat string result too long"
+
[.[] / ","]
["a, bc, def, ghij, jklmn, a,b, c,d, e,f", "a,b,c,d, e,f,g,h"]
[["a"," bc"," def"," ghij"," jklmn"," a","b"," c","d"," e","f"],["a","b","c","d"," e","f","g","h"]]
@@ -1560,3 +1572,7 @@ false
.x - 10
{"x":13911860366432393}
13911860366432382
+
+try 0[implode] catch .
+[]
+"Cannot index number with string \"\""

105
changelog Normal file
View File

@ -0,0 +1,105 @@
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-17
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-16
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Fri Jan 13 2023 Florian Weimer <fweimer@redhat.com> - 1.6-15
- Port configure script to C99
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-14
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Fri Mar 11 2022 Neal Gompa <ngompa@fedoraproject.org> - 1.6-13
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
* Tue Mar 08 2022 Davide Cavalca <dcavalca@fedoraproject.org> - 1.6-12
- Backport PR#2400 to fix iteration for non-decimal strings (rhbz#2017285)
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Wed Sep 29 2021 Davide Cavalca <dcavalca@fedoraproject.org> - 1.6-10
- Backport PR#1752 to fix an integer logic issue (rhbz#2008979)
* Thu Aug 12 2021 Lon Hohberger <lon@redhat.com> - 1.6-9
- Drop build-time RPATH from jq binary (rhbz#1987608)
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Sat Dec 05 2020 Richard W.M. Jones <rjones@redhat.com> - 1.6-6
- Use correct valgrind_arches macro to check for valgrind.
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Thu Nov 08 2018 David Fetter <david@fetter.org> - 1.6-1
- Upstream 1.6.0
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Sun Apr 01 2018 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.5-12
- Rebuild against oniguruma 6.8.1
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Wed Feb 07 2018 Lon Hohberger <lon@fedoraproject.org> - 1.5-10
- Fix CVE 2015-8863
* Fri Feb 02 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.5-9
- Switch to %%ldconfig_scriptlets
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Sun Oct 30 2016 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.5-5
- Rebuild for oniguruma 6.1.1
* Mon Jul 18 2016 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.5-4
- Rebuild for oniguruma 6
* Sun Mar 13 2016 Peter Robinson <pbrobinson@fedoraproject.org> 1.5-3
- valgrind on all but s390
* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Tue Aug 25 2015 Haïkel Guémar <hguemar@fedoraproject.org> - 1.5-1
- Upstream 1.5.0
* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
* Sun Jun 08 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
* Thu Oct 24 2013 Flavio Percoco <flavio@redhat.com> - 1.3-2
- Added check, manpage
* Fri Oct 18 2013 Flavio Percoco <flavio@redhat.com> - 1.3-1
- Initial package release.

View File

@ -1,6 +1,6 @@
--- !Policy --- !Policy
product_versions: product_versions:
- rhel-8 - rhel-10
decision_context: osci_compose_gate decision_context: osci_compose_gate
rules: rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional} - !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

158
jq.spec
View File

@ -1,31 +1,31 @@
# valgrind cannot cope with GCC 13+ SSE4.1 optimizations of strcmp
# https://bugzilla.redhat.com/show_bug.cgi?id=2257546
%bcond check %[!(0%{?rhel} >= 10)]
Name: jq Name: jq
Version: 1.6 Version: 1.7.1
Release: 11%{?dist} Release: %autorelease
Summary: Command-line JSON processor Summary: Command-line JSON processor
License: MIT and ASL 2.0 and CC-BY and GPLv3 License: MIT and ASL 2.0 and CC-BY and GPLv3
URL: http://stedolan.github.io/jq/ URL: https://jqlang.github.io/jq/
Source0: https://github.com/stedolan/jq/releases/download/%{name}-%{version}/%{name}-%{version}.tar.gz Source0: https://github.com/jqlang/jq/releases/download/%{name}-%{version}/%{name}-%{version}.tar.gz
Patch0: 0000-jq-decimal-literal-number.patch Patch1: 0001-CVE-2024-23337.patch
Patch1: 0001-iterration-problem-for-non-decimal-string.patch Patch3: 0002-CVE-2025-48060.patch
Patch2: 0002-add-mantest.patch
Patch3: 0003-fix-pthread-segfault.patch
Patch4: 0004-make-jq-fast.patch
Patch5: 0005-sast.patch
Patch6: 0006-CVE-2024-23337.patch
Patch7: 0007-CVE-2025-48060.patch
BuildRequires: gcc
BuildRequires: flex BuildRequires: flex
BuildRequires: bison BuildRequires: bison
BuildRequires: chrpath
BuildRequires: oniguruma-devel BuildRequires: oniguruma-devel
%ifarch %{valgrind_arches}
BuildRequires: valgrind
%endif
BuildRequires: make
BuildRequires: autoconf BuildRequires: autoconf
BuildRequires: automake BuildRequires: automake
BuildRequires: libtool BuildRequires: libtool
BuildRequires: chrpath
%ifnarch s390x
BuildRequires: valgrind
%endif
%description %description
@ -53,12 +53,12 @@ Development files for %{name}
%prep %prep
%autosetup -n %{name}-%{version} -p1 %autosetup -n %{name}-%{name}-%{version} -p1
%build %build
autoreconf -fi autoreconf -if
%configure --disable-static %configure --disable-static
make %{?_smp_mflags} %make_build
# Docs already shipped in jq's tarball. # Docs already shipped in jq's tarball.
# In order to build the manual page, it # In order to build the manual page, it
# is necessary to install rake, rubygem-ronn # is necessary to install rake, rubygem-ronn
@ -74,129 +74,33 @@ make %{?_smp_mflags}
# $ make real_docs # $ make real_docs
%install %install
make DESTDIR=%{buildroot} install %make_install
find %{buildroot} -name '*.la' -exec rm -f {} ';' find %{buildroot} -name '*.la' -exec rm -f {} ';'
chrpath --delete %{buildroot}/usr/bin/jq
# Delete build-time RPATH that is unnecessary on an installed
# system - rhbz#1987608
chrpath -d %{buildroot}%{_bindir}/%{name}
%if %{with check}
%check %check
# Valgrind used, so restrict architectures for check # Valgrind used, so restrict architectures for check
%ifarch %{ix86} x86_64 %ifarch %{ix86} x86_64
make check make check
%endif %endif
%endif
%ldconfig_scriptlets
%files %files
%license COPYING
%doc AUTHORS COPYING NEWS.md README.md
%{_bindir}/%{name} %{_bindir}/%{name}
%{_libdir}/libjq.so.* %{_libdir}/libjq.so.*
%{_datadir}/man/man1/jq.1.gz %{_datadir}/man/man1/jq.1.gz
%{_datadir}/doc/jq/AUTHORS
%{_datadir}/doc/jq/COPYING
%{_datadir}/doc/jq/README
%{_datadir}/doc/jq/README.md
%files devel %files devel
%{_includedir}/jq.h %{_includedir}/jq.h
%{_includedir}/jv.h %{_includedir}/jv.h
%{_libdir}/libjq.so %{_libdir}/libjq.so
%{_libdir}/pkgconfig/libjq.pc
%changelog %changelog
* Mon Jun 30 2025 Tomas Halman <thalman@redhat.com> - 1.6-11 %autochangelog
- Fix CVE-2025-48060 AddressSanitizer: stack-buffer-overflow in jq_fuzz_execute (jv_string_vfmt)
- Resolves: RHEL-92987
* Mon Jun 30 2025 Tomas Halman <thalman@redhat.com> - 1.6-10
- Fix CVE-2024-23337 jq has signed integer overflow in jv.c:jvp_array_write
- Resolves: RHEL-92968
* Fri May 3 2024 Tomas Halman <thalman@redhat.com> - 1.6-9
- Fix SAST findings in jq 1.6
- Resolves: RHEL-37827
* Fri Oct 13 2023 Tomas Halman <thalman@redhat.com> - 1.6-8
- Make jq 1.6 fast
- Resolves: RHEL-5052
* Tue Mar 14 2023 Tomas Halman <thalman@redhat.com> - 1.6-7
- Fix jq segfault when used in threads
- Resolves: rhbz#2092160
* Fri Nov 4 2022 Tomas Halman <thalman@redhat.com> - 1.6-6
- Add mantest to the gating
- Related: rhbz#2049601
* Tue Oct 11 2022 Tomas Halman <thalman@redhat.com> - 1.6-5
- Remove rpath from jq binary
- Related: rhbz#2049601
* Tue Oct 11 2022 Tomas Halman <thalman@redhat.com> - 1.6-4
- Fix iterration problem for non decimal string
- Resolves: rhbz#2049601
* Mon Oct 4 2021 Tomas Halman <thalman@redhat.com>
- Fix big integers issue
- Resolves: bug#2008717
* Mon Oct 4 2021 Tomas Halman <thalman@redhat.com>
- Releasing v1.6
- Resolves: bug#1852514
* Wed Aug 11 2021 Tomas Halman <thalman@redhat.com>
- Publishing devel package
- Resolves: bug#1908928
* Sat Aug 11 2018 Troy Dawson <tdawson@redhat.com>
- Fix typo: s390 -> s390x
- Related: bug#1614611
* Sun Apr 01 2018 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.5-12
- Rebuild against oniguruma 6.8.1
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Wed Feb 07 2018 Lon Hohberger <lon@fedoraproject.org> - 1.5-10
- Fix CVE 2015-8863
* Fri Feb 02 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.5-9
- Switch to %%ldconfig_scriptlets
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Sun Oct 30 2016 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.5-5
- Rebuild for oniguruma 6.1.1
* Mon Jul 18 2016 Mamoru TASAKA <mtasaka@fedoraproject.org> - 1.5-4
- Rebuild for oniguruma 6
* Sun Mar 13 2016 Peter Robinson <pbrobinson@fedoraproject.org> 1.5-3
- valgrind on all but s390
* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.5-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Tue Aug 25 2015 Haïkel Guémar <hguemar@fedoraproject.org> - 1.5-1
- Upstream 1.5.0
* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
* Sun Jun 08 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
* Thu Oct 24 2013 Flavio Percoco <flavio@redhat.com> - 1.3-2
- Added check, manpage
* Fri Oct 18 2013 Flavio Percoco <flavio@redhat.com> - 1.3-1
- Initial package release.

View File

@ -7,17 +7,12 @@ prepare:
- how: install - how: install
package: package:
- dnf-plugins-core - dnf-plugins-core
- https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
- how: shell
script: /usr/bin/crb enable
- how: install - how: install
package: package:
- jq - jq
- jq-devel - jq-devel
- gcc - gcc
- wget - wget
- how: shell
script: dnf config-manager --disable epel*
execute: execute:
how: tmt how: tmt

View File

@ -1 +1 @@
SHA512 (jq-1.6.tar.gz) = f5ae8be558ca2ff15324c378d623106b74bd0823be50835e23548584aa1eb24eb81f8f054693d5d3fe44f157d0735c5f0f40b9f21899ba068f2a11d1345ace19 SHA512 (jq-1.7.1.tar.gz) = af9c444e5306423182f467a53acdf45bb8aefa058a47f490ce16395f0aebfb7627e3843f65e96f41cd9d4b72b8ad274ab0bdb061abc6990b1158f86d2256d4ec

View File

@ -2,19 +2,30 @@
export LC_ALL=C export LC_ALL=C
stress_jq() { measure_env_speed () {
`which time` -p -f '%e\n' bash -c 'for i in `seq 1 1000` ; do echo '"'"'{"foo":"bar"}'"'"' | jq '"'"'has("bar")'"'"' > /dev/null ; done' 2>&1 | cut -d. -f1 `which time` -p -f '%e\n' bash -c 'for a in `seq 1 1000`; do (for b in `seq 500`; do echo $b; done) | pigz > /dev/null; done' 2>&1
}
stress_jq() {
`which time` -p -f '%e\n' bash -c 'for i in `seq 1 1000` ; do echo '"'"'{"foo":"bar"}'"'"' | jq '"'"'has("bar")'"'"' > /dev/null ; done' 2>&1
} }
FAIL=0
TIME=`stress_jq`
echo -n "Test jqspeed ... " echo -n "Test jqspeed ... "
if [ $TIME -gt 8 ] ; then SPEED=`measure_env_speed`
TIMEOUT=`echo 3.0 '*' $SPEED | bc`
TIME=`stress_jq`
FAIL=`echo $TIME '>' $TIMEOUT | bc`
if [ "$FAIL" = "1" ] ; then
echo "failed" echo "failed"
FAIL=1
else else
echo "ok" echo "ok"
fi fi
echo "Runtime: ${TIME}s "
echo "Speed: ${SPEED}s"
echo "Runtime: ${TIME}s"
echo "Timeout: ${TIMEOUT}s"
exit $FAIL exit $FAIL

View File

@ -3,4 +3,6 @@ require:
- jq - jq
- which - which
- time - time
- pigz
- bc
test: ./jqspeed.sh test: ./jqspeed.sh

View File

@ -15,6 +15,8 @@
- jq-devel - jq-devel
- valgrind - valgrind
- rubygem-rake - rubygem-rake
- pigz
- bc
tests: tests:
- upstream: - upstream:
dir: upstream dir: upstream

View File

@ -5,10 +5,14 @@ die () {
exit 1 exit 1
} }
dnf list jq
dnf remove -y jq
dnf --disablerepo=fedora* --disablerepo=updates* install -y jq jq-devel
# If source not found, download it with dnf # If source not found, download it with dnf
if [ ! -d ./source ]; then if [ ! -d ./source ]; then
# Extract source from srpm # Extract source from srpm
dnf download --source jq && \ dnf --disablerepo=fedora* --disablerepo=updates* download --source jq && \
rpm2cpio jq*.rpm|cpio -id && \ rpm2cpio jq*.rpm|cpio -id && \
mkdir source && \ mkdir source && \
tar -zxf jq-*.tar.gz -C source --strip-components=1 tar -zxf jq-*.tar.gz -C source --strip-components=1