I need to create an XML xPath parser. All parsing has to happen on client side (using javascript). I created an javascript that does this, and everything looks OK until default namespaces come into play. I simply can't query XML that has default namespace.
I created an example code on fiddle. In xmlString is XML string received from server. In xPathString is query done on received XML.
Here are some scenarios:
http://jsfiddle.net/BF34q/1/ - no namespaces - everything works OK
http://jsfiddle.net/BF34q/2/ - ns namespace added. element has ns: prefix. xPath uses this prefix - OK
http://jsfiddle.net/BF34q/3/ - default namespace used - not sure how to configure xPathString.
Note that others will use this parser, so I would really like to avoid solutions like
var xPathString = "//*[local-name()='book']";
and enable them to parse it using simple xPath expressions. I wonder if it is possible to assign default namespace prefix in javascript?
Note: The example provided on fiddle will not work in IE.
I think there are three ways to do this:
Use //*[local-name()='book'] syntax for accessing nodes
Convert XML to string, remove default namespace using RegExp, convert it back to XML
For XML files where you know namespaces in advance, you can create your own namespace resolver, which will allow you to use your own prefix for default namespace.
This can be achieved like this:
function nsResolver(prefix) {
switch (prefix) {
case 'xhtml':
return 'http://www.w3.org/1999/xhtml';
case 'mathml':
return 'http://www.w3.org/1998/Math/MathML';
default:
return 'http://example.com/domain';
}
}
xml.evaluate('//myPrefix:book', xml, nsResolver, XPathResult.ANY_TYPE, null);
I've got the impression that your understanding of the XPath processing doesn't match the implementation - unless, that is, the implementation you're dealing with is very different from the ones I'm familiar with.
Usually, the XPath processor has to have namespaces registered and prefixes mapped to them in order for the expression to be successfully evaluated. So the prefixes could be anything - the only thing that matters is what they're mapped to. See this answer by a known expert to get more information.
Related
I'm using AWS Secrets Manager to pull some environment variables during the deployment process for a React CloudFront Web App. I have not written a ton of javascript - and I'm trying to figure out the best way to extract values from my string of 'secrets' and set them as environment variables.
For some context, I'm able to hook into the AWS-SDK just fine and retrieve my secrets - they look like this:
console.log(secret)
> {"JOE":"https://joe.com","MIKE":"http://mike.com"}
The first surprise came when I decided to check the type of my secret and came to find out javascript is evaluating it as a string:
console.log(typeof secret);
> string
Since I now know I'm working with a string, I'm attempting to find the most efficient way to parse this 'string' (though it looks like a dictionary to my python eyes) and set each key/pair value within the string as environment variables.
The first I tried was the 'modules.export' method - I did something like:
module.exports = secret;
if(process.env.JOE) {
console.log('It is set!');
}
else {
console.log('No set!');
}
Of course, this was too good to be true - and did not appear to work as I'd hoped.
The next thing I tried was simply to try and index the string and see what it might return:
console.log(secret["JOE"]);
> undefined
No luck there.
I have tried a variety of other simple builtin javascript methods but I'm not seeming to make any progress. Am I think correctly that I should first load this into a dictionary, then possibly use modules.export to set each key/pair in the dict as environment variables ?
That looks like a JSON string. Just call JSON.parse(secret) and it should give you the object you expected.
Data from web servers always will return as a string, regardless of its format. Refer to this link: https://www.w3schools.com/js/js_json_parse.asp
This should convert the data to JSON which you can then treat as a regular JavaScript object.
Hope this helps!
Can I put a data breakpoint which triggers if any variable is assigned to a string containing a certain substring?
For example, I want to reverse-engineer how a URL containing &ctoken= is constructed. It's done with complicated JavaScript where the goal is to obfuscate it.
If I could tell the JS VM to monitor all string variables and break when a certain substring appears on any variable, this would help me a lot.
Is this possible?
Before I start - as of my knowledge this is not possible.
What you'd need (even before creating the debugging feature) is the raw string types already boxed to String the native built-in object and String then already proxied.
Some more explanation:
only having
const s = "hi"
is not yet an instance of String - the built-in native object, which is supplied by the ECMAScript implementation to your scope - but a raw type.
Such raw types are nothing more than pointers to a raw data memory reference. I even assume there are built in pools like in Java to optimize cases like
const s = "hi"
const x = new String("hi")
to be the same memory reference of the data object. but the later of course would be boxed by String.
http://bespin.cz/~ondras/html/classv8_1_1String.html
On raw types we couldn't - even if we wanted to - add a subscriber.
for example then:
s.charAt(i)
will autobox s to its wrapper String.
to observe every raw type would mean that we'd have to box all raw strings to String which wouldn't be a good thing for performance at all.
not only that but also the implementation of String itself would have to allow us to add a subscriber and therefore be proxied already.
in JS such proxy would look like this (to make it more understandable what I mean by proxied):
var proxiedString = new Proxy(String, {
defineProperty(target, propKey, propDesc) {
console.log('defined a new string')
},
set(obj, prop, value) {
console.log('set a new value to a string')
}
});
proxiedString.x = 'newPropValue'
and that again I guess - wouldn't be good for performance.
You can use condition breakpoints at browser devTools, by right
click with a menu.
If you can write a js somewhere in a page, you
can do this:
.
if(window.location.pathname.indexOf("&ctoken=") > -1){
debugger;// browser will put breakpoint automaticaly here, if condition is trully.
console.dir(window.location);
}
My web app (running jQuery) gets the following JSON response from the server:
{
"script_0": "$('#objview_0_306').on('click', function(e){ getObjectResponse(96089, '306', 'display'); e.preventDefault();});",
"verb_0": "display",
"obid_0": "0_306",
"body_0": "<div id=\"objview_0_306\"></div>",
"icon_0": "icons/caseman16.png",
"close_0": "previousTab();",
"title_0": "Cases",
"cmdCount": "1"
}
The script_0 element contains scripts that must be run, in this case adding an onClick event to a DOM element.
At the moment, I use eval() to run the scripts, since they are returned as strings. Is there a way to avoid using eval()?
Noop. The eval (and alias Function constructor etc.) is designed to do exactly this, parse strings into runnable javascript.
If you don't want to use eval, instead of return the complete javascript from the server, you can return values in json response that instruct your client app to do predefined tasks.
I'm going to plagiarize the comment made by #Esailija:
Why on earth would you have code in json? it's a data-interchange format...
I do not think that you can achieve what you want without eval or one of its derivates.
You could give a look to jQuery.globalEval() method, as described here: http://api.jquery.com/jQuery.globalEval/
And you could also give a look to the jQuery.getScript() method: http://api.jquery.com/jQuery.getScript/
I'll be the first to spout the usual eval == evil mantra, but im also a realist, and there are times when rules can be broken.
I'd say you might have one of them here.
You can try to append that string with code to DOM and then trigger the click event on needed element.
I have a website that returns a JSON-like data structure like this:
{
"name":"tom jones",
"no": 123,
"storedproc": function(){
callbuyer(0123);
}
}
I'm getting this data using $.ajax() with dataType "JSON". Unfortunately, my $.ajax() calls the error callback because my data contains a function().
How can I parse this correctly? I really need to store the function in a variable and call it later.
That is simply not legal JSON (as you know given the title of the question) See the offical JSON syntax. The nice thing about real JSON is that one can use JSON.parse which safely wraps an eval call.
While eval could be used, I would suggest revisiting the architecture of your application and find some other way to do what you are trying to do.
In particular, I would have the server return the 0123 only, and let your client keep the logic that lets it know, in certain cases, which functions apply (in the scenario here, the function would be callbuyer).
This should work because you say you want to call the function which is the value of the storedproc later. Since the body of this function contains a call to callbuyer it follows that your client side script knows what callbuyer is. The trick is for your server not to send back arbitrary, unconstrained functions, but rather data that your client can exploit somehow using the knowledge it has about the overall application.
Could you arrange to have the server return JSON like this:
{"name":"tom jones",
"no": 123,
"storeprocFn": callbuyer,
"arg": "0123"};
Then your callback function can call the callbuyer function and pass arg
Use eval to interpret the string as a javascript object. You won't be able to use the JSON data type though. I believe what you need to do is use 'text' as the dataType for the $.ajax call. Then do something like:
var data = eval('(' + text + ')');
Should work. Of course, eval is evil. But it would solve your problem. As long as you can guarantee there isn't anything malicious in the text (no unsanitized, user entered data) then you should be ok.
AFAIK, functions are left out when using JSON.stringify, it's just not meant to be used to clone full objects (props and methods). However, you might be able to pass the function body as a string.Say you decide on a string format like func=>var foo = 'bar'; return foo;. This should be passed as a regular JSON string, after parsing the object you could then iterate all properties, and convert those strings to functions like so:
for (var prop in parsedObj)
{
if (parsedObj.hasOwnProperty(prop) && parsedObj[prop].match(/^func\=\>/))
{
parsedObj[prop] = new Function(parsedObj[prop].replace('func=>',''));
}
}
Though, seriously, I'd say you might want to rethink your approach, this is not what JSON is for. It's unsafe, all JSON strings are eval'ed, after having made sure they contain no harmful code. This approach is creating a loophole/vulnerability that the JSON people worked hard for to seal off.
For your example will this work:
'user.storeproc = function() { callbuyer( user.no);};'
The Var 'user' is the object of the parsed json.
Ps: maybe you have to format user.no, from 123 to 0123
Following JSON extension, "JFON", does transport of functions and array-properties.
JFON uses eval and is intended for case if:
1) your data is from trusted source ( like not-derived from user input or is a code from your own server), and
2) you know there are no undesired side effects with context of "eval"
(it is a context of eval in function "fromJFON", line 127 )
3) it is costly to refactor your app to use "functionless" JSON;
4) JFON is one-day work, so may be needs more testing;
The idea: use selected property name to escape functions and arrays like
in strings when selected character "\" is used to pass \n and \ for itself.
In JFON, name "wrap" is selected to pass functions and itself: "wrap" : { "fun" : ... and "wrap" : { "esc" : ...
demo: http://landkey.org/Sandbox/z/spaceen86/js/btb/tests/jfon.htm
code ( use commit 0.0.86 ):
https://github.com/lancelab/spaceen/blob/master/js/btb/JFON.js
test: github.com/lancelab/spaceen/blob/master/js/btb/tests/jfon.htm
Here is another, "JWON" extension: JSON-comments, here-documents, monkey-patching of JSONs:
github.com/lancelab/Boardspirator/blob/master/diary/play/tp/jwon.js
Say I have this function:
function test(){
return a + b + 1;
}
How can I dynamically figure out that it will require globals a and b to be able to run? E.g. something like get_dependencies(test) returns ['a', 'b']
There's no built-in way to do that in standard JavaScript, if you're trying to do it with JavaScript itself.
On nearly all (but not all) JavaScript engines, you can get a form of the source of a function from the function object's toString function, e.g.:
var testSource = test.toString();
...and then of course you could parse that. This is non-standard behavior (the result of calling toString on a function is not defined in the specification), but it's widely-supported. You'd still have to do the parsing to find the symbols.
For the parsing, you have a couple of options. You could try to separate the parser portion of JSLint out of the rest of it, or alternately the terribly-named UglifyJS compressor has a full JavaScript parser which is already separate from the compressor part (see parse-js.js; apparently there's a tiny bit of NodeJS-specific stuff you might want to remove).
You can use a Javascript 'lint' tool that will test your code for common mistakes or oddities.
Some can be found online:
http://www.jslint.com/
http://www.javascriptlint.com/online_lint.php (can also be downloaded)
In your case, you might want to isolate individual functions via a regular expression for example, and submit them to such a tool.