jsonpath: add 2 elements and then compare - javascript

Given the following json data:
[
{
"item":"T1",
"size":10,
"offset":3
},
{
"item":"T2",
"size":20,
"offset":5
}
]
query expr: $.[? ((#size + #offset)<15)].item
the query returns nothing. Anything wrong? it looks like (#size + #offset) is not supported. If so, what is the correct syntax?

I think you might need to try this instead:
$.[? ((#.size + #.offset)<15)].item
Note the dot after each # sign.

With DefiantJS, you can execute XPath on JSON structures.
http://defiantjs.com/
At this site (http://defiantjs.com/#xpath_evaluator), you can paste in your JSON data and try out standard XPath. I have tested your json data and tested this XPath expression, which works as expected:
//*[size + offset > 15]/item
DefiantJS extends the global object JSON with an additional method; "search" and in javascript, it looks like this:
var res = JSON.search(json_data, "//*[size + offset > 15]/item");
console.log(res[0]);
// T2

Related

Convert string with '=' to JSON format

I am trying to convert a string i receive back from an API into a JSON object in Angular.
The issue is that the string is not normalized to be parsed into JSON easily.
This is the string im working with:
"{rootCause=EJBusinessException: This is a sample exception thrown for testing additional info field, description=This is a more detailed description about the incident., stackTrace=com.springboot.streams.infrastructure.web.heartbeat.HeartbeatService.testServiceNow(HeartbeatService.java:200)}"
When trying to do JSON.parse(myStr) it throws an error due to invalid string format.
Is there an easy way to convert the listed string into a more correct JSON format, getting rid of the '=' and replacing them with ':' instead.
There is more to it than just .replace(/['"]+/g, ''), as even with that the string is not ready to be turned into JSON yet.
Hoping someone more versed in Javascript knows a trick i dont.
You just need to manipulate the string before parsing it remove unecessary string that can cause error to the object like "{" and "}" and split it by "," example is in below.
var obj = {}, str = "{rootCause=EJBusinessException: This is a sample exception thrown for testing additional info field, description=This is a more detailed description about the incident., stackTrace=com.springboot.streams.infrastructure.web.heartbeat.HeartbeatService.testServiceNow(HeartbeatService.java:200)}"
str.split(",").forEach((st, i) => {
pair = st.split("=")
if(pair.length > 1) {
obj[pair[0].replace("{",'').replace("}", '').trim()] = pair[1]
} else {
obj[i] = pair
}
})
console.log(obj)
As commenters have posted, unless you control the API or at least have documentation that output will always follow a specific format, then you are limited in what you can do. With your current example, however you can trim off the extraneous bits to get the actual data... (remove braces, split on comma, split on equals) to get your key:value pairs... then build a javascript object from scratch with the data... if you need json string at that point can just JSON.stringify()
var initialString = "{rootCause=EJBusinessException: This is a sample exception thrown for testing additional info field, description=This is a more detailed description about the incident., stackTrace=com.springboot.streams.infrastructure.web.heartbeat.HeartbeatService.testServiceNow(HeartbeatService.java:200)}"
var trimmedString = initialString.substr(1, initialString.length - 2);
var pairArray = trimmedString.split(',');
var objArray = [];
pairArray.forEach(pair => {
var elementArray = pair.split('=');
var obj = {
key: elementArray[0].trim(),
value: elementArray[1].trim()
};
objArray.push(obj);
});
var returnObj = {};
objArray.forEach(element => {
returnObj[element.key] = element.value;
});
console.log(JSON.stringify(returnObj));

javascript is there a way to clean up a string multiple times in a clean way

I'm trying to clean up a JSON string (that was converted from a json object) and I found that many people use the .replace() method to do so. However, in doing so my code looked like this:
scrape(url).then(result => {
final = JSON.stringify(result);
final = final.replace(/['"]+/g, "");
final = final.replace(/[{]+/g, "");
final = final.replace(/[}]+/g, "");
final = final.replace(/[:]+/g, ": ");
final = final.replace(/,+/g, ";");
return final;
});
While this method does work returning 'final' in the way i want it, it does not seem very efficient and the code is really clunky. My end goal is to remove quotes, curly brackets, replace ':' with ': ' and change all commas to semi colons. Is there a better/cleaner way to do this?
EDIT:
The input string looks something like this:
{
'$primary': '#ea80fc',
'$p_light': '#ffb2ff',
'$p_dark': '#b64fc8',
'$secondary': '#b64fc8',
'$s_light': '#f9683a',
'$s_dark': '#870000'
}
Given your actual data, where after JSON.parse you have the following structure:
{
'$primary': '#ea80fc',
'$p_light': '#ffb2ff',
'$p_dark': '#b64fc8',
'$secondary': '#b64fc8',
'$s_light': '#f9683a',
'$s_dark': '#870000'
}
turning this into legal SCSS doesn't require a long chain of replaces applied to the JSON string at all. It just requires parsing the JSON to plain JS object, and then iterating over the key/values to form an SCSS string:
function jsonToSCSS(stringdata=``, data={}) {
/* JSON.parse can throw. Always be ready for that. */
try { data = JSON.parse(stringdata); }
catch (e) { console.warn(e); return ``; }
return Object.keys(data)
.map(key => `${key}: ${data[key]};`)
.join('\n');
}
And done. The output of that function is now a normal, formatted string:
$primary: #ea80fc;
$p_light: #ffb2ff;
$p_dark: #b64fc8;
$secondary: #b64fc8;
$s_light: #f9683a;
$s_dark: #870000;
Which you can now write into whatever file you need it written into, either directly, or itself wrapped in formatting:
const SCSS = jsonToSCSS(inputdata);
const qualified = `.someclass { ${SCSS} }`;
More simplified
scrape(url).then(result => {
return JSON.stringify(result.replace(/['"{}]+/g, "").replace(/[:]+/g, ":").replace(/,+/g, ";"));
});

Replace array-mapped variables with the actual variable name/string?

I am trying to edit a Greasemonkey/jQuery script. I can't post the link here.
The code is obfuscated and compressed with minify.
It starts like this:
var _0x21e9 = ["\x67\x65\x74\x4D\x6F\x6E\x74\x68", "\x67\x65\x74\x55\x54\x43\x44\x61\x74\x65", ...
After "decoding" it, I got this:
var _0x21e9=["getMonth","getUTCDate","getFullYear", ...
It is a huge list (500+ ). Then, it has some variables like this:
month = date[_0x21e9[0]](), day = date[_0x21e9[1]](), ...
_0x21e9[0] is getMonth, _0x21e9[1] is getUTCDate, etc.
Is it possible to replace the square brackets with the actual variable name? How?
I have little knowledge in javascript/jQuery and can not "read" the code the way it is right now.
I just want to use some functions from this huge script and remove the others I do not need.
Update: I tried using jsbeautifier.org as suggested here and in the duplicated question but nothing changed, except the "indent".
It did not replace the array variables with the decoded names.
For example:
jsbeautifier still gives: month = date[_0x21e9[0]]().
But I need: month = date["getMonth"]().
None of the online deobfuscators seem to do this, How can I?
Is there a way for me to share the code with someone, at least part of it? I read I can not post pastebin, or similar here. I can not post it the full code here.
Here is another part of the code:
$(_0x21e9[8] + vid)[_0x21e9[18]]();
[8] is "." and [18] is "remove". Manually replacing it gives a strange result.
I haven't seen any online deobfuscator that does this yet, but the principle is simple.
Construct a text filter that parses the "key" array and then replaces each instance that that array is referenced, with the appropriate array value.
For example, suppose you have a file, evil.js that looks like this (AFTER you have run it though jsbeautifier.org with the Detect packers and obfuscators? and the Unescape printable chars... options set):
var _0xf17f = ["(", ")", 'div', "createElement", "id", "log", "console"];
var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);
var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);
var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];
window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);
In that case, the "key" variable would be _0xf17f and the "key" array would be ["(", ")", ...].
The filter process would look like this:
Extract the key name using text processing on the js file. Result: _0xf17f
Extract the string src of the key array. Result:
keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
In javascript, we can then use .replace() to parse the rest of the JS src. Like so:
var keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
var restOfSrc = "var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);\n"
+ "var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);\n"
+ "var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];\n"
+ "window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);\n"
;
var keyArray = eval (keyArrayStr);
//-- Note that `_0xf17f` is the key name we already determined.
var keyRegExp = /_0xf17f\s*\[\s*(\d+)\s*\]/g;
var deObsTxt = restOfSrc.replace (keyRegExp, function (matchStr, p1Str) {
return '"' + keyArray[ parseInt(p1Str, 10) ] + '"';
} );
console.log (deObsTxt);
if you run that code, you get:
var _0x41dcx3 = eval("(" + '{id: 3}' + ")");
var _0x41dcx4 = document["createElement"]("div");
var _0x41dcx5 = _0x41dcx3["id"];
window["console"]["log"](_0x41dcx5);
-- which is a bit easier to read/understand.
I've also created an online page that takes JS source and does all 3 remapping steps in a slightly more automated and robust manner. You can see it at:
jsbin.com/hazevo
(Note that that tool expects the source to start with the "key" variable declaration, like your code samples do)
#Brock Adams solution is brilliant, but there is a small bug: it doesn't take into account simple quoted vars.
Example:
var _0xbd34 = ["hello ", '"my" world'];
(function($) {
alert(_0xbd34[0] + _0xbd34[1])
});
If you try to decipher this example, it will result on this:
alert("hello " + ""my" world")
To resolve this, just edit the replacedSrc.replace into #Brock code:
replacedSrc = replacedSrc.replace (nameRegex, function (matchStr, p1Str) {
var quote = keyArry[parseInt (p1Str, 10)].indexOf('"')==-1? '"' : "'";
return quote + keyArry[ parseInt (p1Str, 10) ] + quote;
} );
Here you have a patched version.
for (var i = 0; i < _0x21e9.length; i++) {
var funcName = _0x21e9[i];
_0x21e9[funcName] = funcName;
}
this will add all the function names as keys to the array. allowing you to do
date[_0x21e9["getMonth"]]()

Parsing javascript array with multiple keys

Hi I need to parse a JavaScript array that has multiple keys in it. Here is an example of what I need to do. Any help is appreciated.
[
week1{
Meth:100,
Marijuana:122,
pDrugs:12,
},
week2{
Meth:15,
Marijuana:30,
pDrugs:22,
},
]
I need this to be broken into separate arrays based on if it is week1 or week2. Thanks again in advance.
The end needs to be like this.
week1 = ["Meth:100,Marijuana:122,pDrugs12"] etc.
Your JSON has severe improper formatting. If it's already an object (which I'm guessing it isn't -- otherwise, you'd be getting unexpected token errors in your browser console), then change the brackets to braces, remove the trailing commas, and add colons after the object items that don't have them (after week1 and week2).
If what you have is a string (obtained from XHR or similar), you'll have to do all the changes mentioned above, as well as enclosing each object item within quotation marks. It should look like:
{
"week1": {
"Meth":100,
"Marijuana":122,
"pDrugs":12
},
"week2": {
"Meth":15,
"Marijuana":30,
"pDrugs":22
}
}
Whatever you're dealing with that's serving such horribly invalid JSON ought to be taken out back and shot. Be that as it may, this'll require some serious string manipulation. You're going to have to do some thorough massaging with String.replace() and some regular expressions.
After you get the JSON valid, then you can get week1 with JSON.parse and drilling down the resulting object.
function log(what) { document.getElementById('out').value += what + '\n------------------\n'; }
var tree = '[ week1{ Meth:100, Marijuana:122, pDrugs:12, }, week2{ Meth:15, Marijuana:30, pDrugs:22, }, ]';
// string is raw
log(tree);
tree = tree.replace(
'/\r?\n/g', '' // remove line breaks to make further regexps easier
).replace(
'[','{' // replace [ with {
).replace(
']','}' // replace ] with }
).replace(
/\w+(?=[\{\:])/g, // add quotes to object items
function($1) { return '"'+$1+'"'; } // using a lambda function
).replace(
/"\{/g, '": {' // add colon after object items
).replace(
/,(?=\s*\})/g, '' // remove trailing commas
);
// string has been fixed
log(tree);
var obj = JSON.parse(tree);
log('obj.week1 = ' + JSON.stringify(obj.week1));
log('obj.week1.Meth = ' + obj.week1.Meth);
#out {
width: 100%;
height: 170px;
}
<textarea id="out"></textarea>

Dojo Toolkit: how to escape an HTML string?

A user of my HTML 5 application can enter his name in a form, and this name will be displayed elsewhere. More specifically, it will become the innerHTML of some HTML element.
The problem is that this can be exploited if one enters valid HTML markup in the form, i.e. some sort of HTML injection, if you will.
The user's name is only stored and displayed on the client side so in the end the user himself is the only one who is affected, but it's still sloppy.
Is there a way to escape a string before I put it in an elements innerHTML in Dojo? I guess that Dojo at one point did in fact have such a function (dojo.string.escape()) but it doesn't exist in version 1.7.
Thanks.
dojox.html.entities.encode(myString);
Dojo has the module dojox/html/entities for HTML escaping. Unfortunately, the official documentation still provides only pre-1.7, non-AMD example.
Here is an example how to use that module with AMD:
var str = "<strong>some text</strong>"
require(['dojox/html/entities'], function(entities) {
var escaped = entities.encode(str)
console.log(escaped)
})
Output:
<strong>some text</strong>
As of Dojo 1.10, the escape function is still part of the string module.
http://dojotoolkit.org/api/?qs=1.10/dojo/string
Here's how you can use it as a simple template system.
require([
'dojo/string'
], function(
string
){
var template = '<h1>${title}</h1>';
var message = {title: 'Hello World!<script>alert("Doing something naughty here...")</script>'}
var html = string.substitute(
template
, message
, string.escape
);
});
I tried to find out how other libraries implement this function and I stole the idea of the following from MooTools:
var property = (document.createElement('div').textContent == null) ? 'innerText': 'textContent';
elem[property] = "<" + "script" + ">" + "alert('a');" + "</" + "script" + ">";
So according to MooTools there is either the innerText or the textContent property which can escape HTML.
Check this example of dojo.replace:
require(["dojo/_base/lang"], function(lang){
function safeReplace(tmpl, dict){
// convert dict to a function, if needed
var fn = lang.isFunction(dict) ? dict : function(_, name){
return lang.getObject(name, false, dict);
};
// perform the substitution
return lang.replace(tmpl, function(_, name){
if(name.charAt(0) == '!'){
// no escaping
return fn(_, name.slice(1));
}
// escape
return fn(_, name).
replace(/&/g, "&").
replace(/</g, "<").
replace(/>/g, ">").
replace(/"/g, """);
});
}
// that is how we use it:
var output = safeReplace("<div>{0}</div",
["<script>alert('Let\' break stuff!');</script>"]
);
});
Source: http://dojotoolkit.org/reference-guide/1.7/dojo/replace.html#escaping-substitutions

Categories

Resources