jqlang/jq

Core dumped on implode

bendem opened this issue · 10 comments

Was experimenting with jq and came up accross this crash. I have no idea if implode is supposed to work like that, but I think the crash is worth fixing.

Reproduction steps

$ jq implode <<< '[{"key": "x","value": 0}]'

output

jq: jv.c:717: jv_string_implode: Assertion `jv_get_kind(n) == JV_KIND_NUMBER' failed.
Aborted (core dumped)

version

$ jq --version
jq-1.5

backtrace

$ gdb jq <<< 'run implode <<< "[{\"key\": \"x\",\"value\": 0}]"
bt'
(gdb) Starting program: /usr/bin/jq implode <<< "[{\"key\": \"x\",\"value\": 0}]"

Program received signal SIGABRT, Aborted.
0x00007ffff729da28 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55
55    return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
(gdb) bt
#0  0x00007ffff729da28 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55
#1  0x00007ffff729f62a in __GI_abort () at abort.c:89
#2  0x00007ffff7296227 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x7ffff7bc8c78 "jv_get_kind(n) == JV_KIND_NUMBER", 
    file=file@entry=0x7ffff7bc8860 "jv.c", line=line@entry=717, 
    function=function@entry=0x7ffff7bc9090 <__PRETTY_FUNCTION__.4314> "jv_string_implode") at assert.c:92
#3  0x00007ffff72962d2 in __GI___assert_fail (assertion=assertion@entry=0x7ffff7bc8c78 "jv_get_kind(n) == JV_KIND_NUMBER", 
    file=file@entry=0x7ffff7bc8860 "jv.c", line=line@entry=717, 
    function=function@entry=0x7ffff7bc9090 <__PRETTY_FUNCTION__.4314> "jv_string_implode") at assert.c:101
#4  0x00007ffff7babe46 in jv_string_implode (j=...) at jv.c:717
#5  0x00007ffff7ba73dd in f_string_implode (jq=<optimized out>, a=...) at builtin.c:969
#6  0x00007ffff7ba3174 in jq_next (jq=0x55555575a150) at execute.c:784
#7  0x0000555555557298 in process (jq=0x55555575a150, value=..., flags=<optimized out>, dumpopts=513) at main.c:125
#8  0x0000555555555fe1 in main (argc=<optimized out>, argv=0x7fffffffe1f8) at main.c:530
(gdb) quit
A debugging session is active.

    Inferior 1 [process 17476] will be killed.

Quit anyway? (y or n) [answered Y; input not from terminal]

@bendem wrote:

I have no idea if implode is supposed to work like that, but I think the crash is worth fixing.

For the record, implode is intended to be the inverse of explode -- that is, its input is expected to be an array of non-negative integers within a certain range. Since implode does raise an implode-specific error for certain values outside the intended domain, it is reasonable to infer that the intention was for it to raise an error for all such values. Perhaps the fact that it does not reflects some concern about efficiency.

Ah I see, implode / explode are for codepoints. I guessed it was equivalent to php's functions.

Yeah, these are definitely for codepoints. That said, we should never
actually trip an assertion. I'll make a fix for it tonight.

On Sun, Jun 5, 2016 at 1:08 PM bendem notifications@github.com wrote:

Ah I see, implode / explode are for codepoints. I guessed it was
equivalent to php's functions.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#1160 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/ADQ4V-rPB60KhIoX3zFaMyGDCodUbeKnks5qIwJwgaJpZM4IuXYo
.

Reproduced a variation of this on OSX jq while code golfing

 $ jq -Mn '[78,null,83] | implode'
 Assertion failed: (jv_get_kind(n) == JV_KIND_NUMBER), function jv_string_implode, file jv.c, line 717.
 Abort trap: 6
 $ jq --version
 jq-1.5

The issue still exists in the latest git version:

% jq -R '[explode]|sort|implode' <<< $'hello\nolleh'
jq: src/jv.c:729: jv_string_implode: Assertion `jv_get_kind(n) == JV_KIND_NUMBER' failed.
zsh: abort      ./jq -R '[explode]|sort|implode' <<< $'hello\nolleh'
% jq -n '["a"]|implode'
jq: src/jv.c:729: jv_string_implode: Assertion `jv_get_kind(n) == JV_KIND_NUMBER' failed.
zsh: abort      ./jq -n '["a"]|implode'

@nyuszika7h - You are right, but just to make sure everyone knows, both these examples should raise an error condition anyway.

I know those inputs are invalid, but I think it would still be preferable to raise an error rather than a core dump.

The issue is still present (jq-1.6-129-g80052e5). @wtlangford, may I ask you, are you still interested in making a fix?

There is one more assertion that may be violated as a result of calling implode:

$ jq -n '[-2] | implode'
jq: src/jv_unicode.c:101: jvp_utf8_encode: Assertion `codepoint >= 0 && codepoint <= 0x10FFFF' failed.
Aborted (core dumped)

I hit another assertion with this:

$ echo '10000' | jq '[while(. < 9999999; . + 1)] | implode'
[...]
혵혶혷호혹혺혻혼혽혾혿홀홁홂홃홄홅홆홇홈홉홊홋홌홍홎홏홐홑홒홓화확홖홗환홙홚홛활홝홞홟홠홡홢홣홤홥홦홧홨황홪홫홬홭홮홯홰홱홲홳홴홵홶홷홸홹홺홻홼홽홾홿횀횁횂횃횄횅횆횇횈횉횊횋회획횎횏횐횑횒횓횔횕
횖횗횘횙횚횛횜횝횞횟횠횡횢횣횤횥횦횧효횩횪횫횬횭횮횯횰횱횲횳횴횵횶횷횸횹횺횻횼횽횾횿훀훁훂훃후훅훆훇훈훉훊훋훌훍훎훏훐훑훒훓훔훕훖훗훘훙훚훛훜훝훞훟훠훡훢훣훤훥훦훧훨훩훪훫훬훭훮훯훰훱훲훳훴훵훶
훷훸훹훺훻훼훽훾훿휀휁휂휃휄휅휆휇휈휉휊휋휌�jq: src/jv_print.c:127: jvp_dump_string: Assertion `c != -1' failed.
Abortado (imagem do núcleo gravada)
$ jq --version
jq-1.6-129-g80052e5

And my terminal's text became green.

A reduced version of what @bottle2 posted above:

$ jq -n '[55296] | implode'
jq: src/jv_print.c:125: jvp_dump_string: Assertion `c != -1' failed.
Aborted (core dumped)

Any value representing a surrogate code point (between 55296 and 57343) will produce this result.

String literals for comparison:

$ jq -n '"\ud800"'  # unpaired leading surrogate
jq: error: Invalid \uXXXX\uXXXX surrogate pair escape at [...]:
"\ud800"
jq: 1 compile error

$ jq -n '"\udc00"'  # unpaired trailing surrogate
"�" [U+FFFD replacement character]