nodejs json_parse crash on asteriks - json

I listen on a websocket for some data that will be in the following format:
'{"mode": "test", "code": "' + editor.getValue() + '", "testTeam": "basic"}'
The users will write some code that we then will run in a sandbox.
When i parse the data with data = JSON.parse(message); it crash if it get the character * asterisk.
What is so special with * that makes it crash? I though of just removing them but that will destroy user comments in the code.

Instead of this:
'{"mode": "test", "code": "' + editor.getValue() + '", "testTeam": "basic"}'
use this:
JSON.stringify({mode: "test", code: editor.getValue(), testTeam: "basic"})
to have a correct JSON string.
What probably happens is that editor.getValue() contains quotes or newlines and you are not escaping them correctly.
This is just a guess because you didn't provide an actual example of message before parsing but you should never compose JSON directly with string concatenation. Use JSON.stringify() to serialize JavaScript objects to JSON.
Also always put JSON.parse() and JSON.stringify() inside of try/catch to avoid crashing on bad input or use a module like tryjson that does that for you:
https://www.npmjs.com/package/tryjson
Both JSON.parse() and JSON.stringify() can throw exceptions.

Related

AWS Lambda Error : 'Could not parse request body into json ' when url parameter contains JSON array

I am trying to invoke my Lambda function by passing parameters as below. it contains apostrophe(').
https://invoke_url?param=[["kurlo jack's book","Adventure Books",8.8,1]]
Stringifyed to be 'https://invoke_url?param=%5B%5B%229780786706211%22s....`
I used the mapping below to pass parameter to lambda
"query": {
#foreach($queryParam in $input.params().querystring.keySet())
"$queryParam": "$util.escapeJavaScript($input.params().querystring.get($queryParam))" #if($foreach.hasNext),#end
#end
}
I got following error
{"message": "Could not parse request body into json: Unrecognized character escape \'\'\' (code 39)\n at [Source: [B#5b70c341; line: 29, column: 65]"}
i have also tried after removing double quotes from mapping template. But did't work.
Be sure to add .replaceAll("\\'","'") to your request body passthrough template after .escapeJavaScript(data)
I found this bit from AWS's documentation to be very helpful for this issue:
$util.escapeJavaScript()
Escapes the characters in a string using JavaScript string rules.
Note This function will turn any regular single quotes (') into
escaped ones (\'). However, the escaped single quotes are not valid in
JSON. Thus, when the output from this function is used in a JSON
property, you must turn any escaped single quotes (\') back to regular
single quotes ('). This is shown in the following example:
$util.escapeJavaScript(data).replaceAll("\\'","'")
I don't have a solution but I have narrowed the root cause. Lambda does not seem to like single quotes to be escaped with a single slash.
If you hardcode your mapping template to look like this:
{
"query-fixed": {
"param": "[[\"kurlo jack\\'s book\",\"Adventure Books\",8.8,1]]"
}
}
my test Lambda invocation succeeds. However, if you hardcode the template to this:
{
"query-fixed": {
"param": "[[\"kurlo jack\'s book\",\"Adventure Books\",8.8,1]]"
}
}
I get the same error message that you got above. Unfortunately, the second variation is what API Gateway produces for the Lambda invocation.
A workaround might involve using the template to replace single quotes escaped with slash to two slashes. See Replace a Substring of a String in Velocity Template Language
I'll follow up with Lambda internally and update if I hear anything or have a functional workaround.
Try changing your encoding of ' to %27 as per what is is defined in this W3Schools page (ironically their example does not encodes the single quote either, I guess its because it belongs to the "supported" ASSCII set of characters)
The "query string" (the part in the hyperlink after ?) must be a string. Whatever you have constructing that must be appended to it like: https://invoke_url?a=x&b=y
In your Lambda code put:
if( event.hasOwnProperty( 'params' ) )
if( event.params.hasOwnProperty( 'querystring' ) )
params = event.params.querystring;
(obviously some extraneous checks, probably unnecessary but ehh)
In your API Gateway go to:
APIs -> api_name -> Resources -> invoke_url -> GET -> Method Execution
Under URL Query String Parameters "Add query string" a and b (or whatever)
When you hit www.com/invoke_url?a=x&b=y you can now access them with:
...
params = event.params.querystring;
console.log( params.a, params.b );
...

Ruby parse string to json

So I have some json that looks like this, which I got after taking it out of some other json by doing response.body.to_json:
{\n \"access_token\": \"<some_access_token>\",\n \"token_type\": \"Bearer\",\n \"expires_in\": 3600,\n \"id_token\": \<some_token>\"\n}\n"
I want to pull out the access_token, so I do
to_return = {token: responseJson[:access_token]}
but this gives me a
TypeError: no implicit conversion of Symbol into Integer
Why? How do I get my access token out? Why are there random backslashes everywhere?
to_json doesn't parse JSON - it does the complete opposite: it turns a ruby object into a string containing the JSON representation of that object is.
It's not clear from your question what response.body is. It could be a string, or depending on your http library it might have already been parsed for you.
If the latter then
response.body["access_token"]
Will be your token, if the former then try
JSON.parse(response.body)["access_token"]
Use with double quotes when calling access_token. Like below:
to_return = {token: responseJson["access_token"]}
Or backslashes are escaped delimiters and make sure you first parse JSON.

Azure Stream Analytics Error :Could not deserialize the input event as Json

I am trying to create a Stream Analytics job. The message is being sent in the following format as JSON:
var message = "Name;\n" + Guid.NewGuid().ToString() + ";" ;
When I am running my job I am getting the following error:
Could not deserialize the input event as Json. Some possible reasons:
1) Malformed events
2) Input source configured with incorrect serialization format
Based on your code sample, it appears your input is taking the form of:
Name;
AA7509E7-D482-459B-9689-456A0F952B44;
then the error message you're seeing is correct, this is not valid JSON, so ASA won't be able to deserialize it. Your JSON string should look something like this:
{
"Name": "AA7509E7-D482-459B-9689-456A0F952B44"
}

NodeJS create JSON array for Slack incoming webhook

I am currently working on getting my incoming Webhook application written in Node.JS to get work with this API: https://api.slack.com/incoming-webhooks.
My problem is that the JSON string for Slack has to configured with " these quotation marks and if I create a simple JSON string in Node.JS, Slack says that the string isn't valid.
var text = "New Commit";
var form = '{"text": "' + text + '" }';
The above code works, but looks pretty ugly and when I add a \n' to indicate a new line, the \n is directly converted into a new line and not sent within the string, so Slack says again the JSON string isnt valid.
As mentioned by tandrewnichols I need to use JSON.stringify and create an object.

How to avoid quotes when encoding a JSON object

I need to create something like the following JSON entity:
{
"foo": function() { *some code* }
}
Can any of the common JSON libraries (json, jsonb, aeron etc.) easily achieve that?
I didn't find a way to tell the library not to quote the function part when encoding.
Thanks,
p.s. I understand the reason for not allowing such usage is to enforce correct syntax, but I'm willing to take that risk here.
That is not a JSON entity, but a JavaScript object. JSON has no concept of functions.
The only way to have a function encoded in JSON is indeed to encode it in a string:
{ "foo": "function() { return \"Hello, World\" }" }
When you want to execute that function in JavaScript, you'll have to eval the string:
var jsonObj = JSON.parse('{ "foo": "function() {return \\"Hello, World\\";}" }');
var jfoo = eval('(' + jsonObj.foo + ')');
alert(jfoo()); // Shows a dialog box "Hello, World"
Note that this allows the source of the JSON to execute arbitrary JavaScript in the context of your website or application. Therefore, you should transfer data instead of functions whenever possible, and make sure not to eval code from untrusted sources.