In C23 (default C standard used by GCC 15), jv (*fptr)(); has become
equivalent to jv (*fptr)(void); so we can no longer assign builtin
implemenations directly to the fptr member of cfunctions without
generating a compile error.
Since there does not seem to be any straight-forward way to tell
autoconf to force the compiler to use C99 short of explicitly adding
-std=c99 to CFLAGS, it is probably a cleaner solution to just make the
code C23 compatible.
A possible solution could have been to just redeclare cfunction.fptr
as void*, but then the functions' return type would not have been type
checked (e.g. if you tried to add a {printf, "printf", 2}, where printf
is a function that does not return jv, the compiler wouldn't have
complained.)
We were already not typechecking the arguments of the functions, so e.g.
{binop_plus, "_plus", 3}, /* instead of {f_plus, "_plus, 3}, */
{f_setpath, "setpath", 4}, /* instead of {f_setpath, "setpath", 3}, */
compile without errors despite not having the correct prototype.
So I thought of instead improving the situation by redefining
cfunction.fptr as a union of function pointers with the prototypes that
the jq bytecode interpreter can call, and use a macro to add the builtin
functions to function_list using to the arity argument to assign the
implementation function to the appropriate union member.
Now the code won't compile if the wrong arity, or an arity not supported
by the bytecode interpreter (>5 = 1input+4arguments), or a prototype not
jallable by the bytecode interpreter (e.g. binop_plus that doesn't
expect a jq_state* argument).
Also, the code now compiles with gcc -std=c23.
Fixes#3206
This check was redundant and useless since jv2tm() used to require 8
elements, and errored anyway if not enough elements were provided.
After commit bc96146, this check also prevents mktime/0 from accepting
now supported inputs with less than 8 elements.
Ref: https://github.com/jqlang/jq/pull/3070#issuecomment-2299902072
Reported-by: itchyny <itchyny@cybozu.co.jp>
Now, time functions accept array inputs even if they don't have all the
elements, 0 will be assumed if a value is not present.
Also, jv2tm now properly clamps large number values to a signed 32-bit
integer and rejects nan.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65885
There was a incorrect else, that caused jq to not ensure that the
argument to strftime/1 is a string when the input is a number; this ends
up calling jv_string_value on a non-string value, which does not work,
and causes an assert failure.
Also fix same bug in strflocaltime/1.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=67403
Previously, the tonumber/0 filter parses the input as JSON values, but
this is less-performant on large non-number strings. Parsing the input
string as number literal fixes the performance issue. Also, this fix
changes the filter to reject numbers with white spaces.
C99 only allows string literals long at most 4095 characters.
jq_builtins was a lot longer than that.
I rewrote all the optional libm error stubs in C so the value of
jq_builtins is not build dependent.
I replaced the command that generates builtin.inc with a POSIX compliant
od|sed command that encodes builtin.jq as a comma delimited list of
octal numbers (that can be embedded in C using a {} literal).
I also added -Woverlength-strings to AM_CFLAGS to verify that the
problem is fixed.
Fixes#1481
Previously, ltrimstr/rtrimstr would just let the input pass through for
non-string inputs or arguments.
That was happening because, they were leaking the errors returned by
startswith/endswith treating them as if they were jv_false().
The leak was resolved by #2977 for 1.7.1
This patch rewrites ltrimstr and rtrimstr in jq, and makes them not
ignore startswith and endswith errors anymore.
ltrimstr/rtrimstr was ignoring and leaking the error returned by
f_startswith()/f_endswith().
This also means that they just let the input pass through for non-string
inputs or arguments.
Only fix the leak for now; in the next release, #2969 will make them
rethrow the error returned by startswith/endswith.
Ref: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64946
* Build windows 64bit binary using UCRT64
Is the default and recommended msystem setting. Will produce
binaries that are compatible with windows 10 and later.
Also run tests for 32bit build.
Related to #2831
* Use jq -b in tests/shtest
* Add Windows strptime
* Make Windows-optional tests not run on Windows again
---------
Co-authored-by: Nicolas Williams <nico@cryptonector.com>
This patch exports all the binary operator builtins functions from
builtin.c and uses them for constant folding in the parser, allowing
constant folding to work will all kinds and combinations of constants.
Now string*number, $ARGS+$ARGS, string/string, etc will also be
constant folded and the implementation of constant folded operators and
runtime operators will be the same.
And thanks to the new ERRORK bytecode operation, errors are constant
folded too! (e.g. 1 / 0 [] * {} etc)
Previously constant folding of zero division (e.x. 1/0) produces a
compile error. This was incorrectly implemented by checking if the
division result is infinite, so produces wrong results compared to the
query where no constant folding is processed (e.x. 1e308/0.1). This
patch delays the operation when the divisor is zero. This makes the
results more consistent, but changes the exit code on zero division from
3 to 5. Also 0/0 now produces the zero division error, not NaN.
This patch also fixes the modulo operation. Previously constant folding
logic does not take care of the % operator, but now it folds if the both
dividend and divisor are safe numbers to cast to the integer type, and
the divisor is not zero. This patch also fixes some code that relies on
undefined cast behaviors in C. The modulo operation produces NaN if
either the dividend or divisor is NaN.
You only need to specify the return type in a function pointer
declaration in C.
If you use () in the declaration, the function pointer can be called
with any arguments, and the type of the arguments is decided for each
function call based on the types of the arguments used for the call.
(To declare a function pointer for a function with no arguments, you use
`(void)'.)
Since all the cfunction structs have a fptr that points to a functions
that return jv, not void, we can we can just declare cfunction.fptr as
jv (*)() and avoid having those annoying and technically not C-standard
compliant casts everywhere.
Error on non-number and nan codepoint, would asserd before
Replace negative codepoint and surrogate range with unicode replacement character, would assert before
Fixes#1160
This is unnecessary since we are using AC_USE_SYSTEM_EXTENSIONS in
configure.ac, which makes the compiler always run with -D_GNU_SOURCE=1
when building for GNU/Linux.
Also, the #define _GNU_SOURCE in src/util.c, and in
src/inject_errors.c (--enable-inject-errors), were not guarded by a
#ifndef _GNU_SOURCE so they were just triggering redefinition warnings.
Instead of just using {"captures":[]}.
sub functions are use captures for replacement expressions.
If we don't populate, captures for empty matches, the replacement
expression is run with an empty object as input instead of an object
containing the named captures with "" as value:
* before:
$ jq -n '"123foo456bar" | gsub("[^a-z]*(?<x>[a-z]*)"; "Z\(.x)")'
"ZfooZbarZnull"
* after:
$ jq -n '"123foo456bar" | gsub("[^a-z]*(?<x>[a-z]*)"; "Z\(.x)")'
"ZfooZbarZ"
---
I also removed a redundant
result = NULL;
if (result) {
...
}
The primary purpose of this commit is to rectify most problems with
`gsub` (and also `sub` with the `g` option), in particular fix#1425 ('\b'),
fix#2354 (lookahead), and fix#2532 (regex == `"^(?!cd ).*$|^cd "`).
This commit also partly resolves#2148 and resolves#1206 in that
`gsub` no longer loops infinitely; however, because the new `gsub`
depends critically on `match/2`, the behavior when regex == `""` is
sometimes non-standard.
The documentation has been updated to reflect the fact that `sub`
and `gsub` are intended to be regular in the second argument.
Also, `_nwise/1` has been tweaked to take advantage of TCO.
Extend jv_number to use decNumber for storing number literals. Any math
operations on the numbers will truncate them to double precision.
Comparisons when both numbers are literal numbers will compare them
without truncation.
Delay conversion of numbers to doubles until a math operation is performed,
to preserve precision. A literal jv_number will only need conversion to
double once, and will reuse the resultant double on subsequent
conversions.
Outputting literal jv_numbers preserves the original precision.
Add strong pthread requirement to manage contexts/allocations for
converting numbers between their decNumber, string, and double formats.
block_bind_incremental is block_bind_referenced in a loop backwards. For
an 1-inst block, it does the same thing and isn't too much more
expensive, so it's not really useful to keep both.
Also, block_bind_referenced was a better name for the function.