"%" is getting URI decoded while everyhting else not - javascript

I have a strange UI5 problem. I create a string from a control's binding context which looks like:
Entity('Element%3AInfo%2CID')
Just for info, it looks like this decoded: Entity('Element:Info,ID')
However, I get this String from the following method chain:
oItem.getBindingContext().getPath().substr(1)
So, the whole (pretty basic) "navigate to" block looks like this:
showElement : function (oItem) {
'use strict';
var bReplace = jQuery.device.is.phone ? false : true;
sap.ui.core.UIComponent.getRouterFor(this).navTo("element", {
from: "master",
element: oItem.getBindingContext().getPath().substr(1),
otherpattern: "something"
}, bReplace);
},
A console log in this block console.log(oItem.getBindingContext().getPath().substr(1)); provides the right string.
Console output of console.log(oItem.getBindingContext().getPath().substr(1)):
Entity('Element%3AInfo%2CID')
The problem is (be aware, this is getting curious) that my URL pattern "{element}" is filled with:
Entity('Element%253AInfo%252CID')
Decoded: Entity('Element%3AInfo%2CID')
As you probably already know, the pattern's "%" is encoded. I don't get why UI5 would do this.
You should also know these facts which I've tested:
decodeURIComponent(oItem.getBindingContext().getPath().substr(1)) leads to "Entity('Element:Info,ID')"
encodeURIComponent(oItem.getBindingContext().getPath().substr(1)) leads to "Entity('Element%25253AInfo%25252CID')"
oItem.getBindingContext().getPath().substr(1).replace("%3A", ":") leads to "Entity('Element:Info%252CID')"
Is this a bug? I mean the URI pattern is left untouched as long as it doesn't come to a "%". For some odd reason this special character is encoded while everything else doesn't matter.

Its not exactly like "%" is getting encoded and everything else is not encoded.
I also came across this issue. SAPUI5 does encoding once, and browser does it second time. Hence in the second iteration you will have only "%" to be encoded.
Initial string : Element:Info,ID
after first iteration of encoding(by UI5 framework) encodeURIComponent('Element:Info,ID') : We get Element%3AInfo%2CID
So for the second iteration, only % is left to be encoded Element%253AInfo%252CID hence we get this.
So if you are picking up the binding context from URL, you need to decode twice.
Else as you are doing once is fine.

Related

Reading windows registry Reg_SZ in javascript

first time posting here!:)
As title says I have a win reg fie (reg_sz) which contains "name" and "value"
this.reg = new Registry.Key(Registry.windef.HKEY.HKEY_CURRENT_USER, 'Path\Path\Path', Registry.windef.KEY_ACCESS.KEY_READ);
funct read(this.reg){
var value;
var pushes = [];
[
"food",
"veggy",
"etc",
"etc"].forEach(function(name) {
try {
value = key.getValue(name);
entries.push({name: name, value: value});
} catch (e) {
}
});
return pushes;
};
example: "food"="apple"
Which my code reads properly, however I came across a issue with special characters, example "ä"
"food"="äpple"
which my code reads as �pple.
My question is what kind of decoding/encoding should i use and what is with this win registry, what exactly are they using? Can it be raw JS preferably and if not what else? I tried using decodeURI/encodeURI but seems like its not the correct approach(dont know what encoding they are using and which decoding should I use)
TLDR: How can i type in "äpple" in win registry and when reading that file with JS get same "äpple" instead of "�pple"
It looks like you're using windows-registry-node. This is unfortunately a bug in that, #44. The reporter says:
If i return the raw buffer and use iconv to convert from "ISO-8859-1" to "UTF-8" i get the correct characters
Note that this is assuming the current code page of the system, though, and might not always be correct. (It might be possible to tell iconv to detect and use the current code page?)
The exact problem is in registry.js:
// READ VALUE
result = advApi.RegQueryValueExA(key.handle.deref(), valueName, null, pKeyType, value,
pKeyDataLength);
Here it uses RegQueryValueExA, which means fetch strings as the current Windows code page, as opposed to RegQueryValueExW which would use UTF-16. So value, which is a Node.JS Buffer, does not contain UTF-8. The code then calls Buffer.toString(), which assumes UTF-8 by default:
if (value.type === types.LPTSR) {
// TODO not sure why buffer's utf8 parsing leaves in the unicode null
// escape sequence. This is a work-around (at least on node 4.1)
value = value.toString().replace('\u0000', '');
}
So this is going to need a fix in windows-registry-node. The best fix is probably to set the code up for UTF-16, using the -W version of the function and value.toString('utf16le');

"Fixing" JSON coming out of MySQL

I'm fetching JSON code stored in MySQL and it has extra slashes, which I have to remove in order to parse it in JavaScript, after I print it on the page. Right now I'm doing the following:
$save = str_replace("\n", "<br>", $save); // Replace new line characters with <br>
$save = str_replace('\\"', '"', $save); // top-level JSON
$save = str_replace('\\\\"', '\"', $save); // HTML inside top level JSON
$save = str_replace('\\\\\\\\\\"', '\\\\\"', $save); // HTML inside second level JSON
Here is an example JSON code, as it comes out from MySQL:
{\"id\":2335,\"editor\":{\"selected_shape\":\"spot-7488\"},\"general\":{\"name\":\"HTML Test\",\"shortcode\":\"html-test\",\"width\":1280,\"height\":776},\"spots\":[{\"id\":\"spot-7488\",\"x\":9.9,\"y\":22.6,\"default_style\":{\"use_icon\":1},\"tooltip_content\":{\"content_type\":\"content-builder\",\"plain_text\":\"<p class=\\\"test\\\">Test</p>\",\"squares_json\":\"{\\\"containers\\\":[{\\\"id\\\":\\\"sq-container-293021\\\",\\\"settings\\\":{\\\"elements\\\":[{\\\"settings\\\":{\\\"name\\\":\\\"Paragraph\\\",\\\"iconClass\\\":\\\"fa fa-paragraph\\\"},\\\"options\\\":{\\\"text\\\":{\\\"text\\\":\\\"<p class=\\\\\\\"test\\\\\\\">Test</p>\\\"}}}]}}]}\"}}]}
And here is how it's supposed to look in order to get parsed correctly (using jsonlint.com to test):
{"id":2335,"editor":{"selected_shape":"spot-7488"},"general":{"name":"HTML Test","shortcode":"html-test","width":1280,"height":776},"spots":[{"id":"spot-7488","x":9.9,"y":22.6,"default_style":{"use_icon":1},"tooltip_content":{"content_type":"content-builder","plain_text":"<p class=\"test\">Test</p>","squares_json":"{\"containers\":[{\"id\":\"sq-container-293021\",\"settings\":{\"elements\":[{\"settings\":{\"name\":\"Paragraph\",\"iconClass\":\"fa fa-paragraph\"},\"options\":{\"text\":{\"text\":\"<p class=\\\"test\\\">Test</p>\"}}}]}}]}"}}]}
Please note that I have HTML code inside JSON, which is inside another JSON and this is where it gets a bit messy.
My question - is there a function or library for PHP (for JS will work too) which covers all those corner cases, because I'm sure someone will find a way to break the script.
Thanks!
The short answer, which is woefully inadequate, is for you to use stripslashes. The reason this answer is not adequate is that your JSON string might have been escaped or had addslashes called on it multiple times and you would have to call stripslashes precisely once for each time this had happened.
The proper solution is to find out where the slashes are being added and either a) avoid adding the slashes or b) understand why the slashes are there and respond accordingly. I strongly believe that the process that creates that broken JSON is where the problem lies.
Slashes are typically added in PHP in a few cases:
magic_quotes are turned on. This is an old PHP feature which has been removed. The basic idea is that PHP used to auto-escape quotes in incoming requests to let you just cram incoming strings into a db. Guess what? NOT SAFE.
add_slashes has been called. Why call this? Some folks use it as an incorrect means of escaping data before sticking stuff in a db. Others use it to keep HTML from breaking when echoing variables out (htmlspecialchars should probably be used instead). It can also come in handy in a variety of other meta situations when you are defining code in a string.
When escaping data input. The most common escaping function is mysqli_real_escape_string. It's very important to escape values before inserting them in a db to prevent sql injection and other exploits but you should never escape things twice.
So there's a possibility that your code is double-escaping things or that addslashes is getting called or something like magic_quotes is causing the problem, but I suspect it is another problem: some JS code might be supplying this JSON not as a proper JSON string, but one that has been escaped so to define a string within javascript.
If you take your example JSON string above, and slap some quotes around it:
var myJSON = "<put your string here>";
then SURPRISE your javascript is not broken and the var myJSON contains a string that is actually valid JSON and can be parsed into an a valid JSON object:
var myJSON = "{\"id\":2335,\"editor\":{\"selected_shape\":\"spot-7488\"},\"general\":{\"name\":\"HTML Test\",\"shortcode\":\"html-test\",\"width\":1280,\"height\":776},\"spots\":[{\"id\":\"spot-7488\",\"x\":9.9,\"y\":22.6,\"default_style\":{\"use_icon\":1},\"tooltip_content\":{\"content_type\":\"content-builder\",\"plain_text\":\"<p class=\\\"test\\\">Test</p>\",\"squares_json\":\"{\\\"containers\\\":[{\\\"id\\\":\\\"sq-container-293021\\\",\\\"settings\\\":{\\\"elements\\\":[{\\\"settings\\\":{\\\"name\\\":\\\"Paragraph\\\",\\\"iconClass\\\":\\\"fa fa-paragraph\\\"},\\\"options\\\":{\\\"text\\\":{\\\"text\\\":\\\"<p class=\\\\\\\"test\\\\\\\">Test</p>\\\"}}}]}}]}\"}}]}";
console.log(JSON.parse(myJSON)); // this is an actual object
The key here is to examine the point of entry where this JSON arrives in your system. I suspect some AJAX request has created some object and rather than sending valid JSON Of that object, it is sending instead an escaped string of a JSON object.
EDIT:
Here's a simple example of what happens when you have too many encodings. Try running this JS in your browser and observe the console output:
var myObj = {"key":"here is my value"};
console.log(myObj);
var myJSON = JSON.stringify(myObj);
console.log(myJSON);
var doubleEncoded = JSON.stringify(myJSON);
console.log(doubleEncoded);

Javascript- if statement in Chrome keepvid script

Sorry if this is stupidly easy, but I don't even program in java.
There's keepvid.com, and they have nice script to get downloads from youtube.
Code:
javascript:(
function(){
window.open('http://keepvid.com/?url='+encodeURIComponent(location.href)+'')
}
)();
I managed to tinker with it so it takes me directly to mp3 download (adding '&mode=mp3'), but it didn't work with long url's with playlists and stuff, so I made one which cuts it off. Code:
javascript:(
function(){
var url=location.href;
url=url.substring(0, url.indexOf('&'));
window.open('http://keepvid.com/?url='+encodeURIComponent(url)+'&mode=mp3')
}
)();
Ultimately I want it to work in all cases, but if url is clean it pastes '&', I tried using IF and it works for manually written true/false, but I cant get it to work with .contains. Code:
javascript:(
function(){
var url=location.href;
if(url.contains('&')){
url=url.substring(0, url.indexOf('&'));
};
window.open(
'http://keepvid.com/?url='+encodeURIComponent(url)+'&mode=mp3'
)
}
)();
I assume you looked at the console. If you had, you would have seen an error such as "undefined is not a function", on the line where you call contains. contains is undefined because there is no method contains on strings.
There was a Firefox-specific String#contains which was changed to includes to match the ES6 spec. Some libraries may provide their own contains method on strings.
You will find includes in few if any browsers as of yet. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes. See also http://kangax.github.io/compat-table/es6/#String.prototype.contains. You can find a polyfill, which looks slightly over-engineered to me, at https://github.com/mathiasbynens/String.prototype.includes.
Instead of checking if url contains '&' as condition I set
if(url.indexOf('&')!=-1)
which states 'if index of "&" is not -1' (I guess -1 is value for not found)

Too much recursion error using crossfilter

The following page loads in Chrome, but in Firefox/IE the error "too much recursion" happens in the crossfilter.js script (crossfilter.js).
Link:http://bit.ly/1epx0Gs
How can this be avoided (or debugged)?
EDIT
Turns out that Chrome can parse dates with dashes ("6-12-2013"), but firefox/ie need spaces ("6 12 2013")
There's not really any way I can verify that this is the problem without a runnable example, but you probably have non-naturally-ordered values in your dimensions. You need to cast your dimension values and make sure that all your values are valid. The relevant section looks to be:
self.data.push({
index:index,
starttime:new Date(d.starttime),
sex:d.gender == '' ? 'Non-Subscriber' : d.gender,
value:d.count
})
I'd at least change this to:
self.data.push({
index:+index,
starttime:new Date(d.starttime),
sex:d.gender == '' ? 'Non-Subscriber' : '' + d.gender,
value:+d.count
})
The Date() could still be tripping you up if you have invalid d.starttime values, so if you are still getting the error you may want to try replacing it with just "new Date()".
Again, no guarantee that's causing your issue, but when I get these recursion errors, this is usually the cause.
I just encountered the same problem, but the solution was not in the date format but in the encoding of the JS-file itself. Maybe this will help someone else.
I was using following dimension to do some filtering:
CF_data = crossfilter(data);
CF_data_id = CF_data.dimension(function(d) { return +d.properties['Código']; });
Notice the spanish "o" character in the selector of the return statement.
And the following error was thrown:
# too much recursion crossfilter.js:174:9
After checking everything, I noticed that my file was suddenly encoded in ANSI and not in UTF8. So in notepadd++ I converted the file back to UTF8 and the error was gone.

remove double quotes from Json return data using Jquery

I use JQuery to get Json data, but the data it display has double quotes. It there a function to remove it?
$('div#ListingData').text(JSON.stringify(data.data.items[0].links[1].caption))
it returns:
"House"
How can I remove the double quote? Cheers.
Use replace:
var test = "\"House\"";
console.log(test);
console.log(test.replace(/\"/g, ""));
// "House"
// House
Note the g on the end means "global" (replace all).
For niche needs when you know your data like your example ... this works :
JSON.parse(this_is_double_quoted);
JSON.parse("House"); // for example
The stringfy method is not for parsing JSON, it's for turning an object into a JSON string.
The JSON is parsed by jQuery when you load it, you don't need to parse the data to use it. Just use the string in the data:
$('div#ListingData').text(data.data.items[0].links[1].caption);
Someone here suggested using eval() to remove the quotes from a string. Don't do that, that's just begging for code injection.
Another way to do this that I don't see listed here is using:
let message = JSON.stringify(your_json_here); // "Hello World"
console.log(JSON.parse(message)) // Hello World
I also had this question, but in my case I didn't want to use a regex, because my JSON value may contain quotation marks. Hopefully my answer will help others in the future.
I solved this issue by using a standard string slice to remove the first and last characters. This works for me, because I used JSON.stringify() on the textarea that produced it and as a result, I know that I'm always going to have the "s at each end of the string.
In this generalized example, response is the JSON object my AJAX returns, and key is the name of my JSON key.
response.key.slice(1, response.key.length-1)
I used it like this with a regex replace to preserve the line breaks and write the content of that key to a paragraph block in my HTML:
$('#description').html(studyData.description.slice(1, studyData.description.length-1).replace(/\\n/g, '<br/>'));
In this case, $('#description') is the paragraph tag I'm writing to. studyData is my JSON object, and description is my key with a multi-line value.
You can simple try String(); to remove the quotes.
Refer the first example here: https://www.w3schools.com/jsref/jsref_string.asp
Thank me later.
PS: TO MODs: don't mistaken me for digging the dead old question. I faced this issue today and I came across this post while searching for the answer and I'm just posting the answer.
What you are doing is making a JSON string in your example. Either don't use the JSON.stringify() or if you ever do have JSON data coming back and you don't want quotations, Simply use JSON.parse() to remove quotations around JSON responses! Don't use regex, there's no need to.
I dont think there is a need to replace any quotes, this is a perfectly formed JSON string, you just need to convert JSON string into object.This article perfectly explains the situation : Link
Example :
success: function (data) {
// assuming that everything is correct and there is no exception being thrown
// output string {"d":"{"username":"hi","email":"hi#gmail.com","password":"123"}"}
// now we need to remove the double quotes (as it will create problem and
// if double quotes aren't removed then this JSON string is useless)
// The output string : {"d":"{"username":"hi","email":"hi#gmail.com","password":"123"}"}
// The required string : {"d":{username:"hi",email:"hi#gmail.com",password:"123"}"}
// For security reasons the d is added (indicating the return "data")
// so actually we need to convert data.d into series of objects
// Inbuilt function "JSON.Parse" will return streams of objects
// JSON String : "{"username":"hi","email":"hi#gmail.com","password":"123"}"
console.log(data); // output : Object {d="{"username":"hi","email":"hi#gmail.com","password":"123"}"}
console.log(data.d); // output : {"username":"hi","email":"hi#gmail.com","password":"123"} (accessing what's stored in "d")
console.log(data.d[0]); // output : { (just accessing the first element of array of "strings")
var content = JSON.parse(data.d); // output : Object {username:"hi",email:"hi#gmail.com",password:"123"}" (correct)
console.log(content.username); // output : hi
var _name = content.username;
alert(_name); // hi
}
I had similar situation in a Promise just solved doing a cast as (String)
export async function getUserIdByRole(userRole: string): Promise<string> {
const getRole = userData.users.find((element) => element.role === userRole);
return String (getRole?.id);
}

Categories

Resources