Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Invalid Numeric Literal" on colon following a single-quoted string (incorrect parser error message) #501

Closed
bartgrantham opened this issue Jul 24, 2014 · 52 comments · Fixed by #2964

Comments

@bartgrantham
Copy link

EDIT (20150416): I KNOW IT'S INVALID JSON. THE BUG IS ABOUT THE NONSENSICAL ERROR MESSAGE

I get this from absent-mindedly and incorrectly using single-quotes:

$ echo "{'foo':'bar'}" | jq .foo
parse error: Invalid numeric literal at line 1, column 7

This is under 1.3. Trying to reproduce under 1.4, but after 5 minutes of trying to build from source I'm just going to submit this and move on.

@pkoppstein
Copy link
Contributor

@bartgrantham - Later versions produce the same (confusing) error message, e.g.

$ jq --version
jq-1.4-100-g0f89270
$ echo "{'foo':'bar'}" | jq .foo
parse error: Invalid numeric literal at line 1, column 7

The simplest demonstration of the issue may be:

echo "'" | jq  .
parse error: Invalid numeric literal at line 2, column 0

@stedolan
Copy link
Contributor

This is a very long-standing issue with the JSON parser (not the parser for jq code, but the parser for JSON input). Essentially, the logic is: is it an array? nope. is it an object? nope. (...) well, it must be a number. parse error on a number.

I suppose the fix is probably to choose a different error message if the invalid character is not in [0-9+-].

@bergerjac
Copy link

according to json.org a string is to be "wrapped in double quotes"

so, use double and escape from echo's

$ echo "{\"foo\":\"bar\"}" | jq .foo
"bar"

@wtlangford
Copy link
Contributor

We've found the best practice to be single quotes around json data and also
your jq program.

$ echo '{"foo":"bar"}' | jq '.foo'

It allows you to use double quotes without escaping and prevents the shell
from attempting to process them.

Also, 1.4 should exist as precompiled binaries on the website and is also
in most package manager repositories.

On Sun, Nov 23, 2014, 11:44 Jacob Berger [email protected] wrote:

according to json.org http://www.json.org/ a string is to be "wrapped
in double quotes"

so, use double and escape from echo's

$ echo "{"foo":"bar"}" | jq .foo

"bar"


Reply to this email directly or view it on GitHub
#501 (comment).

@bartgrantham
Copy link
Author

@bergerjac, @wtlangford - I know single-quotes for strings are wrong, I mentioned at the beginning that I "absent-mindedly and incorrectly" used them. The issue is that the error produced is cryptic.

@wtlangford
Copy link
Contributor

Good point. I might look into a better error for the parser, but the issue
with that is the parser does "is it an object?" "Is it an array?" "Is it a
string?" "Must be a number!".
The current master gives a slightly better error, but I've also seen it
fail an assertion, depending on what I pass in.

On Sun, Nov 23, 2014, 12:29 Bart Grantham [email protected] wrote:

@bergerjac https://github.com/bergerjac, @wtlangford
https://github.com/wtlangford - I know single-quotes for strings are
wrong, I mentioned at the beginning that I "absent-mindedly and
incorrectly" used them. The issue is that the error produced is cryptic.


Reply to this email directly or view it on GitHub
#501 (comment).

@nicowilliams
Copy link
Contributor

Of course, the Windows cmd.exe isn't... as advanced as the typical Unix shell.

We really need something like a REPL to make Windows jq users happy...

@delip
Copy link

delip commented Apr 9, 2015

Ok, I have a big json dump (sql export) that gives this error. Any work-arounds to make it work with jq until this error is fixed?

@pkoppstein
Copy link
Contributor

@delip - Since you have a big JSON dump, you are presumably reading it in as a file. In that case, from what you write, it would seem that the error message you see will give the line and column numbers of the invalid JSON. Thus it is unclear to me what kind of work-around you would like. That is, if your big json dump is invalid JSON, the simplest thing to do might be to fix it.

@nicowilliams
Copy link
Contributor

@delip You have to give us an example.
@bartgrantham That's not JSON. JSON uses double-quotes -not single-quotes- for strings.

If the request is to have more sensible error messages from the JSON parser, that's another story.

@bartgrantham
Copy link
Author

@nicowilliams, I know! I said it in the opening post that it was "incorrect", the bug is about the error messages being misleading. I even wrote it again in this thread, barely a page up from your comment:

I know single-quotes for strings are wrong, I mentioned at the beginning that I "absent-mindedly and incorrectly" used them. The issue is that the error produced is cryptic.

@bartgrantham bartgrantham changed the title "Invalid Numeric Literal" on colon following a single-quoted string "Invalid Numeric Literal" on colon following a single-quoted string (incorrect parser error message) Apr 16, 2015
@nicowilliams
Copy link
Contributor

Heheh, sorry @bartgrantham.

@forging2012
Copy link

PLS use cat /tmp/data.log | jq .
Do not use grep "KEY" /tmp/data.log | jq .

@wtlangford
Copy link
Contributor

wtlangford commented Jun 12, 2018 via email

@wtlangford
Copy link
Contributor

Great!

@rahul5591
Copy link

How i can update value of existing key using jw in shell script

@simesy
Copy link

simesy commented Dec 14, 2019

This error came up for me using jq . < output-json.sh but disappeared when I did output-json.sh | jq .. I don't know why but maybe it will help someone (googling initially led me here).

@bartgrantham
Copy link
Author

@simesy That's because you're sending the content of output-json.sh itself into jq, not the output of running that command. It's the same as jq . < somedata.json.

If you really want to redirect the output of your shell script into jq with input redirection, you can do it in bash with jq . <(output-json.sh), but IMHO the pipe syntax you're using is much clearer to read.

@sandikodev
Copy link

whoo use curl then parse to jq like 'curl http://req.url/get | jq .' then get error like on top. just add -s on curl, like ' curl -s http://req.url/get | jq .' and everything be alright

@chet-manley
Copy link

Curious why this was closed? v1.6 still outputs the same nonsense error if the input is not valid JSON.

$ printf '%s' " ' " | jq .
parse error: Invalid numeric literal at EOF at line 1, column 3
$ echo $?
4

@afontenot
Copy link

@chet-manley yeah, I think maybe @wtlangford closed this by accident thinking it was a different bug report? This should be re-opened IMO.

% jq --version
jq-1.6
% echo "{'test': 'test'}" | jq
parse error: Invalid numeric literal at line 1, column 8

@nkhoury-payments
Copy link

Should definitely be re-opened.

@m-dunbar
Copy link

m-dunbar commented Feb 5, 2021

@nkhoury-payments

Issue #501 has AGAIN been closed incorrectly, after apparently being incorrectly cross-linked with unrelated issues.

This issue is about the misleading error message "Invalid numeric literal" when the error is the use of a single quote.

bartgrantham commented on May 11, 2020
@nkhoury-payments This issue is not about single quotes vs. double quotes. This issue is about the misleading error message "Invalid numeric literal" when the error is the use of a single quote. That's what @chet-manley was referring to, and what this issue is about.

Incidentally, it would be a huge mistake for jq to start supporting non-standard single quotes in JSON.

@TheNetworkIsDown
Copy link

Can someone please reopen. This issue has not been adressed. A few more years and we can celebrate a decade.

@queglay
Copy link

queglay commented Apr 5, 2021

I am also getting this in jq 1.6

@queglay
Copy link

queglay commented Apr 5, 2021

I have a payload (a certificate actually that is now destroyed) that is this:

{
  "request_id": "68366d13-83ac-20de-ea2e-f03120eb21c5",
  "lease_id": "",
  "lease_duration": 0,
  "renewable": false,
  "data": {
    "data": {
      "file": "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",
      "format": "base64",
      "gid": "1002",
      "owner": "deadlineuser",
      "permissions": "0640",
      "uid": "1002"
    },
    "metadata": {
      "created_time": "2021-04-05T09:13:22.454953362Z",
      "deletion_time": "",
      "destroyed": false,
      "version": 39
    }
  },
  "warnings": null
}

And if I try to read it, with this command it will error:

echo "$payload" | jq -r '.data.data.file' | base64 --decode | sudo tee $target_path
parse error: Invalid numeric literal at line 1, column 7

Is this a bug or am I doing it wrong?

@bartgrantham
Copy link
Author

bartgrantham commented Apr 5, 2021

@queglay - This is unrelated to this issue.

As for your problem, I put the JSON in a file and was able to extract and base64-decode it properly with: cat test.json | jq -r '.data.data.file' | base64 --decode > payload. I would guess that your problem is trying to pass JSON through a shell variable. The double-quotes are probably getting mangled somewhere in there.

I would suggest being very careful with a shell construction like this. You're piping an opaque blob of base64-encoded data through sudo tee. That's probably ok if you have high confidence of what the value of $target_path will be, but it resembles the syntactically similar sudo tee $contents_of_file_blob, which could be dangerous. A foggy-headed refactor putting variables in the wrong places could leave this open for exploitation. You've probably already considered it, but I wanted to point it out as it made my "potential security bug" circuit fire.

@queglay
Copy link

queglay commented Apr 5, 2021

Interestingly, I can perform the operation without issue in a shell, but if run during a user data script on boot in ubuntu 18 on ec2, then the error crops up, so I can't reproduce it adhoc.

Thanks for sharing your concern re the potential security bug. I have high confidence over the origin of both values, but honestly hadn't considered what you mention here. For my education sake if someone wanted to do harm by manipulation of $target_path what would an example be?

@bartgrantham
Copy link
Author

Interestingly, I can perform the operation without issue in a shell, but if run during a user data script on boot in ubuntu 18 on ec2, then the error crops up, so I can't reproduce it adhoc.

Maybe do echo "$payload" > test.json and check test.json manually to make sure it looks the way you expect it to? (check a hexdump of it too, just in case)

For my education sake if someone wanted to do harm by manipulation of $target_path what would an example be?

/bin/sh, /etc/passwd, /etc/sudoers, /boot/vmlinuz, ... That's off the top of my head, but I'm not a security researcher. I'm sure they have a whole playbook of exploits based around the toehold of being able to overwrite a file on a victim's machine.

@pkoppstein
Copy link
Contributor

@queglay - I have verified that with your JSON, echo "$payload" | jq -r '.data.data.file'works properly with all extant versions of jq (jq 1.3, 1.4, 1.5, 1.6 and 1.6 master).

For future reference, please ask usage questions related to jq at stackoverflow.com using the jq tag:
https://stackoverflow.com/questions/tagged/jq, being sure to follow the SO guidelines at
http://stackoverflow.com/help/mcve

@cescoferraro
Copy link

I solved my issue by using printf instead of echo

@phocheng
Copy link

phocheng commented Mar 8, 2022

You can do something like
eval "jq '.[\"${your_key}\"]' ${file_path}"

@tronar
Copy link

tronar commented Jul 17, 2024

This is old and may be referred somewhere else, but I got this message because the input was UTF-16. In my case, to me that was not self evident... HTH

@A1vinSmith
Copy link

A1vinSmith commented Sep 10, 2024

cat context.txt | ./convert_to_json.py | jq

python script.py | ./convert_to_json.py | jq

#!/usr/bin/env python3
import sys
import json
import ast

def convert_to_json(input_str):
    # Safely evaluate string to Python object
    try:
        python_dict = ast.literal_eval(input_str)
        return json.dumps(python_dict)
    except (SyntaxError, ValueError) as e:
        return json.dumps({"error": f"Failed to parse input: {str(e)}"})

if __name__ == "__main__":
    # Read from stdin
    input_data = sys.stdin.read().strip()
    
    # Convert and print to stdout
    print(convert_to_json(input_data))

@wader
Copy link
Member

wader commented Sep 10, 2024

@A1vinSmith not sure i follow the relation to this issue. this covert python ast to json?

@A1vinSmith
Copy link

A1vinSmith commented Sep 10, 2024

Hi @wader, based on comments from previous discussions, this script addresses the issues that were raised. It can also be a feature of jq, like jq -enhance

echo "{'foo':'bar'}" | jq
jq: parse error: Invalid numeric literal at line 1, column 7

vi convert_to_json.py
chmod +x convert_to_json.py

echo "{'foo':'bar'}" | ./convert_to_json.py | jq
{
  "foo": "bar"
}

@chet-manley
Copy link

Your example uses truly invalid JSON, and is not what this issue is about.

@bartgrantham
Copy link
Author

Just use tr:

$ echo "{'foo':'bar'}" |  tr "\"'" "'\"" | jq
{
  "foo": "bar"
}

@A1vinSmith
Copy link

Your example uses truly invalid JSON, and is not what this issue is about.

Hi Chet, Do you see the first post under the thread? #501 (comment)

EDIT (20150416): I KNOW IT'S INVALID JSON. My solution solved exactly it.

@chet-manley
Copy link

EDIT (20150416): I KNOW IT'S INVALID JSON. THE BUG IS ABOUT THE NONSENSICAL ERROR MESSAGE

Your solution is not relevant to the issue being raised, and it even says so in the edit. The JSON is invalid on purpose to showcase the nonsensical error message raised. We are not attempting to solve parsing invalid JSON, only the error message produced. Invalid JSON should never be parsable, by design.

@bartgrantham
Copy link
Author

Invalid JSON should never be parsable, by design.

I'd like to emphasize this. If the "JSON" is malformed, it's not JSON. IMHO jq absolutely should not have a feature where it supports invalid JSON by some kind of transformation. The great value of JSON is that it's minimal and rigorously defined, compromising on that is a mistake.

@wader
Copy link
Member

wader commented Sep 12, 2024

Unrelated to this issue but jq has text manipulation support and a fromjson function so one can do something like:

$ echo "{'foo':'bar'}" | jq -R "gsub(\"'\"; \"\\\"\") | fromjson"
{
  "foo": "bar"
}

@bartgrantham
Copy link
Author

Glorious day! The decade-old issue is resolved!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.