So there is an old code base I am leveraging from work, currently they are sending over 2 items from an object and I'm adding a third. The third object I'm sending in JAVA as a string, however in the communication over to javascript it's freaking out, I'm getting a horrible error as prototype is declaring it undefined, however I'm watching the code being sent.
Currently the Java code is calling the function. Passing the following data over. All of these are strings.
setCCInfo(xxxxxxxxxxxxxx2205, 1219, 60W76W);
When I remove the final variable, and pass just the first two the function works, however it's almost like prototype is expecting a numeral as I had to change the other two into strings when it got to the front end. I'll attach the code below. The current Error I'm getting is
"prototype-1.6.0.2.js:394 Uncaught SyntaxError: Invalid or unexpected
token
at prototype-1.6.0.2.js:394
at prototype-1.6.0.2.js:635
at prototype-1.6.0.2.js:595
at Array.forEach ()
at Array.each (prototype-1.6.0.2.js:594)
at Array.collect (prototype-1.6.0.2.js:634)
at String.evalScripts (prototype-1.6.0.2.js:394)
at Function. (prototype-1.6.0.2.js:209)
at prototype-1.6.0.2.js:231"
ctx.getResponse().getWriter().print(output.getString("TCResultStatus").toUpperCase());
StringBuilder str = buildJavascriptCall(cceft);
ctx.getResponse().getWriter().print(str.toString());
private StringBuilder buildJavascriptCall(CcEft cceft) {
StringBuilder str = new StringBuilder();
str.append("<script type='text/javascript'>setCCInfo(");
str.append(cceft.getMaskedCCNum());
str.append(", ");
str.append(cceft.getCombinedExpDate());
str.append(", ");
str.append(cceft.getBillingId());
str.append(");</script>");
return str;
}
Related
I am using jdk11, graal.js script engine .
We get two json string messages, one has rules/condition(jsRules) and the other one has message. If the value in message satisfies the condition in jsRules it should evaluate to 1 else 0 .
So for example in the below code as String "message" has code: CU_USER hence the jsRules condition
header.code == 'CU_USER'
should have been satisfied and hence the eval below should have printed 1 , but instead it gives 0. Kindly explain what is causing this behavior and how can I get the desired behavior ? .
public static void process()
{
int eval =-2 ;
String jsRules = "{(header.code == 'CU_USER' || header.subcode == 'SD_CODE')?1:0}";
String message = "{code:'CU_USER'}";
ScriptEngine graalEngine = new ScriptEngineManager().getEngineByName("Graal.js");
//graalEngine.put("header",message);
try {
graalEngine.eval("var header = unescape(" + message + ")");
eval = (int)graalEngine.eval(jsRules);
System.out.println("Eval value:: "+eval);
} catch (ScriptException e) {
e.printStackTrace();
}
}
You call unescape({code:'CU_USER'}) while unescape expects a String. Thus, the object you provide as argument is converted to a String (to [object Object] actually) and thus the header variable on the JavaScript side holds a String, not an Object as you expect.
The solution would be to simply remove the unescape, i.e. use graalEngine.eval("var header = " + message); instead.
An alternative solution would be to pass in a Java object. You seem to have tried that with the commented out graalEngine.put("header",message); line. Note that I suppose don't want to pass in a Java string; what you typically want to pass in was a Java object that has a code field. Note that for this to work you need to enable the hostAccess permission to the engine (for more details, check https://github.com/graalvm/graaljs/blob/master/docs/user/ScriptEngine.md).
solution draft:
public static class MyMessageObj {
public String code = "CU_USER";
}
ScriptEngine graalEngine = new ScriptEngineManager().getEngineByName("graal.js");
Bindings bindings = graalEngine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("polyglot.js.allowHostAccess", true);
graalEngine.put("header", new MyMessageObj());
eval = (int) graalEngine.eval(jsRules);
During my coding I made a mistake by calling a function like this
someFunction( 'abc' [someValue] )
I had forgotten the colon inside the function call.
After I found the error I played around.
An assignment like this does not throw an error as well.
let a = 'abc'[someValue];
I would expect a syntax error here. Is there an explanation for this?
A string in Javascript can behave as an object and, as such has properties such as .length and methods such as .slice. So, for any property access on an object in Javascript, one can use either the dot notation as in:
str.length
or the [] syntax as in:
str["length"]
or using a variable:
let len = "length";
str[len]
So, what you have with:
'abc' [someValue]
Is just that syntax. A string followed by a property access. That is legal Javascript. It attempts to get the property from that object with the name of whatever string is in the someValue variable.
Here's are a couple working examples:
// simple property access
let prop = "length";
console.log("abc"[prop]);
// method call
console.log("one fine day"["slice"](4, 8));
One would not generally code this way with a string, but it's perfectly legal as it's just part of how one can access properties on an object in Javascript.
Because that's not a syntax error. The engine thought you were trying to get a letter from that string, so if someValue was a number it will work perfectly fine
let a = "abc"[0]
console.log(a, "abc"[1]) //a, b
I have Angular service and in that service I have a code:
this.testMethod = function( ) {
this.jsonTest = "[{'id':'123','title':'XYZ','id2':'456','status':2}]";
this.parseTest(this.jsonTest);
};
this.parseTest = function(jsonTest) {
var jsonTestObj = JSON.parse(jsonTest); // I get error hear
}
Test method is getting called on ng-click event.
Error that I am getting while testing in latest chrome browser:
SyntaxError: Unexpected token ' at Object.parse (native)
......
I tried multiple things to fix it but nothing seems to work.
Every time I get undefined value error.
Basically I want to parse JSON object and get the values.
What am I doing wrong?
Use this
this.jsonTest = '[{"id":"123","title":"XYZ","id2":"456","status": "2"}]';
Or this
this.jsonTest = "[{\"id\":\"123\",\"title\":\"XYZ\",\"id2\":\"456\",\"status\": \"2\"}]";
You either need to use ' outside or " outside and escape the quotes inside.
Both the key and value need to be in double quotes.
You need to use double quotes in your string, other than that your code should work.
To quote from specification
A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.
Your JSON is not valid. Always check your JSON integrity in those cases, i personaly use
http://jsonlint.com/
May need a Javascript language lawyer for this one:
var s1 = "{\"x\":\"y:z\"}"
var o = JSON.parse(s1)
var s2 = JSON.stringify(o)
$('span#s').text(s1);
$('span#s2').text(s2);
if (s1 === s2) {
$('span#areEqual').text('s1 === s2')
} else {
$('span#areEqual').text('s1 !== s2')
}
JSON.parse(s2) // okay
$('span#jsonParse').text("JSON.parse(s2) okay")
eval(s2) // bad mojo!
$('span#eval').text("eval(s2) okay")
eval("("+s2+")") // bad mojo, too!
$('span#eval2').text("eval((s2)) okay")
eval fails on s1, s2, and "("+s2+")".
jsFiddle here.
Your problem is that you mixing two unrelated things.
eval() is built-in javascript function, which main purpose is to interpret string of javascript code (thus make potentional security hole)
JSON.parse() function is for parse JSON string. Although very simmilar, do not make mistake, JSON is not Javascript and there are tiny differences. You should not use eval() for parsing JSON
What are the differences between JSON and JavaScript object?
$eval is automatically evaluated against a given scope.
For example:
$scope.a = 2;
var result = $scope.$eval('1+1+a');
// result is 4
$parse does not require scope. It takes an expression as a parameter and returns a function. The function can be invoked with an object that can resolve the locals:
For example:
var fn = $parse('1+1+a');
var result = fn({ a: 2 });
// result is 4
When you use eval for parsing JSON you need to wrap your expression with parentheses
eval('(' + s2 + ')');
jsfiddle
Check out what the specification says about JSON and eval
http://www.json.org/js.html
Notice this part specifically
The eval function is very fast. However, it can compile and execute
any JavaScript program, so there can be security issues. The use of
eval is indicated when the source is trusted and competent. It is much
safer to use a JSON parser. In web applications over XMLHttpRequest,
communication is permitted only to the same origin that provide that
page, so it is trusted. But it might not be competent. If the server
is not rigorous in its JSON encoding, or if it does not scrupulously
validate all of its inputs, then it could deliver invalid JSON text
that could be carrying dangerous script. The eval function would
execute the script, unleashing its malice.
JSON is just a javascript object, and nothing more. Valid javascript could include functions, execution blocks, etc. If you just eval() a string, it could have code it in. JSON will parse if it's just JSON, but you can't know for sure by just stuffing it into eval. For example
var s = "(function(){ /* do badStuff */ return {s: 123, t: 456}; })()";
var result = eval(s);
Would give you a var result with the contents {s: 123, t: 456} but would also execute any code hidden in your function. If you were taking this input from elsewhere, code could be executing and not actually break anything on your end. Now the same example with JSON.parse
var result = JSON.parse(s);
It throws an error with the message:
Uncaught SyntaxError: Unexpected token (
So the parse saves you from remote code execution here, even if someone tried to sneak it in.
eval wasn't an expression - i've updated it to evaluate eval(s2 === s1);
Otherwise it will try & execute what's within the eval & stop execution.
eval() attempts to evaluate a block of JavaScript code. If you had created a script file that started with the same text, you would have gotten the same error. In that context, I believe the braces signify a compound statement, as in an if-statement or for-statement body, but at the beginning of the compound statement is a string followed by a colon, which is not valid syntax.
If you wanted a string that would evaluate to an object, you'd have to enclose the object expression in parentheses to make it explicit that it's an expression. But as apocalypz says, you should not attempt to eval JSON. It's wrong on so many levels.
if you really want to use eval instead of JSON.parse() for parsing JSON then you should write something like
var o2; // declare o2 out of eval in case of "use strict"
eval("o2 = "+s1); // parse s1 and the assignment to the local o2
console.log(o2); // enjoy the local variable :)
...
Been trying to create a JavaScript object member that always contains a common string. Whenever I create a new object, instead of concatenating the string, it overwrites it with the passed value on creation. If it matters (I don't think it does) the string contains numbers. Par example:
function myObj(strToConcat){
this.combinedString = "Hello " + strToConcat, /* have used + and .concat() without success */
}
var newObj = new myObj("1.2.3");
console.log(newObj.combinedString); /* says "1.2.3", the leading "Hello " is absent */
Can't seem to get this to concatenate the strings.
EDIT: I apologize, the error was outside the code that I thought responsible. Disregard please. My apologies.
You have error in your reference
console.log(myObj.combinedString);
should be
console.log(newObj.combinedString);
Running your code gives me SyntaxError: Unexpected token }. Replace the , at the end of the second line with a ; and I get the expected result of "Hello 1.2.3".