Unexpected Behavior From JavaScript Split function (Chrome/Firefox) - javascript

I add a string (i.e. 'Bob Smith') from a jQuery click event trapped using the on function . . .
$(".vendorLookup").on("click", { fullName: $(this).text() }, displayAddy);
In the displayAddy handler for the click event, I extract the string (a persons first and last name) and split out the first and last name . . .
var name = event.data.fullName;
var parts = name.split(" ");
IE can figure this one out but Chrome and Firefox will not split unless I use the regular expression split(/\s/) (unless I use the w3schools.com Tryit code editor and then it works).
Question: what exactly is going on here and when will I get bit by this later on when parsing for spaces cross-browser?
(Note: I don't think it matters but I am running this script on a wiki page in SharePoint 2010)

I'm not sure whats going on (I tested it and see some weird behavior), but you can work around it by doing something like this
function displayAddy() {
var parts = $(this).text().split(" ");
$('#fname').html(parts[0]);
$('#lname').html(parts[1]);
}
$('#name').on("click", displayAddy);
Since the event is being passed off to a callback the callback already has a this object. in this instance the this object is going to be DOM object with the class #name.
Here's an example of it in action.

Related

Javascript calling Function() to create a function

Can anyone explain the following code?
Function(
Function(
'return \'\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175\''
) ()
)()
Interesting here: an actual function is getting created using the Function().
But since I cannot view the native code, I am having difficulty understanding the actual function that is getting created. This is taken from root-me.org Javascript - native code challenge.
It deobfuscates to:
a = prompt('Entrez le mot de passe');
if(a=='toto123lol'){
alert('bravo');
} else{
alert('fail...');
}
To verify, in Chrome, open Developer Tools, open the console, and paste in:
Function(
'return \'\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175\''
) ()
This is the steps of "how the encoding works", essentially. To "encode" the letter "a":
test = "a";
console.log(test.charCodeAt(0)); //97
console.log(parseInt('141', 8)); //97
console.log('\141'); //a
But since I cannot view the native code, I am having difficulty understanding the actual function that is getting created.
You have native code inside the script tag. It just looks unusual as it is referencing the ASCII key codes; octagonal to be exact (OCT). Here is a link
ASCII Key Codes
First we have an executable tag that starts things off. Here is a link explaining what it does.
HTML tags
Inside the tag we have two functions or function constructors.
If your were to type Function() into your console you would get
function anonymous() {}
For more information check out this link.
Funciton JS link
Let's start with the nested function first.
Function(
'return \'\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175\'')()
By using the JS Function constructor, we can pass in arguments to our new function as well as the function body.
new Function ([arg1[, arg2[, ...argN]],] functionBody)
In the nested function we just create an anonumous funciton and pass it a function body in the form of a string like this
'return \'\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175\''
When the function runs the first string '' (quotes) are removed and this statement is run
return \'\\141\\75...'
The return, of course executes and exits the function, and when THIS function is run we get another function body in the form of another string value.
"a=prompt('Entrez le mot de passe');if(a=='toto123lol'){alert('bravo');}else{alert('fail...');}"
The leading '\', which is after the return statement, but before the actual string is only to escape the following quote, so the compiler does not mistake it for the second closing quote of the quote just before the return statement. We could get rid of it, as well as the second one just after the last number, and instead write the function body like this
Function(
'return "\\141\\75\\160\\162\\157\\155\\160\\164\\50\\47\\105\\156\\164\\162\\145\\172\\40\\154\\145\\40\\155\\157\\164\\40\\144\\145\\40\\160\\141\\163\\163\\145\\47\\51\\73\\151\\146\\50\\141\\75\\75\\47\\164\\157\\164\\157\\61\\62\\63\\154\\157\\154\\47\\51\\173\\141\\154\\145\\162\\164\\50\\47\\142\\162\\141\\166\\157\\47\\51\\73\\175\\145\\154\\163\\145\\173\\141\\154\\145\\162\\164\\50\\47\\146\\141\\151\\154\\56\\56\\56\\47\\51\\73\\175"')()
If you ran this code in your console you would get the same result, try it!
If you do you will find that all these numbers have compiled to actual letters and numbers, in fact it compiled to ASCII character codes. This happened because of the use of '\' which proceeds each number. For less confusion, let's turn this "\\" instead into this "\"
Function(
'return "\141\75\160\162\157\155\160\164\50\47\105\156\164\162\145\172\40\154\145\40\155\157\164\40\144\145\40\160\141\163\163\145\47\51\73\151\146\50\141\75\75\47\164\157\164\157\61\62\63\154\157\154\47\51\173\141\154\145\162\164\50\47\142\162\141\166\157\47\51\73\175\145\154\163\145\173\141\154\145\162\164\50\47\146\141\151\154\56\56\56\47\51\73\175"')()
As you will see, this will still run and we get
"a=prompt('Entrez le mot de passe');if(a=='toto123lol'){alert('bravo');}else{alert('fail...');}"
So the nested function returns a function body as a string, which then gets executed in the outer Function constructer in the same way that the nested function fired. Here is the same example with a few things removed for better clarity
Function(
Function('return "\141\75\160\162\157\155\160\164\50\47\105\156\164\162\145\172\40\154\145\40\155\157\164\40\144\145\40\160\141\163\163\145\47\51\73\151\146\50\141\75\75\47\164\157\164\157\61\62\63\154\157\154\47\51\173\141\154\145\162\164\50\47\142\162\141\166\157\47\51\73\175\145\154\163\145\173\141\154\145\162\164\50\47\146\141\151\154\56\56\56\47\51\73\175"')())()
Note: you may need to open a new window and then paste this in the console and click enter.
And for even more clarity, we could just copy and paste the initial returned value into the outer function like this
Function("a=prompt('Entrez le mot de passe');if(a=='toto123lol'){alert('bravo');}else{alert('fail...');}")()
This will also work.
What the nested function does
The first part opens a browser prompt window and attaches its future value to variable 'a'. Try this
Function("a=prompt('Enter Password');console.log(a);")()
when you press enter your value will show in the console. The second part of the function analizes this returned value by comparing it to a string 'toto123lol'.
when the entered value is exactly 'toto123lol' a new alert window will appear displaying 'bravo'.
If the entered value is not exactly 'toto123lol' a new alert window will appear displaying 'fail...'
As you can see, the initial function of your question contains all the needed information to not only run working code, but also all the native code you need to figure out what it is doing.
After checkout out the website you mentioned
Root-me.org
Perhaps what the test is trying to show is that what may look like harmless code, can actually be anything with could be executable within an HTML tag. Or perhaps that there are many ways in which to influence behavior?
I hope this answers your question.
UPDATE: If you are wondering what the difference is between '\\' or '\' I have asked it here - why double or single escapes

Pass multiple values with onClick in HTML link

Hi Im trying to pass multiple values with the HTML onclick function. Im using Javascript to create the Table
var user = element.UserName;
var valuationId = element.ValuationId;
$('#ValuationAssignedTable').append('<tr> <td>Re-Assign </td> </tr>');
But in my Javascript function the userName is undefined and the valuationId is a string with the valuationId and the UserName combined
function ReAssign(valautionId, userName) {
valautionId;
userName;
}
If valuationId and user are JavaScript variables, and the source code is plain static HTML, not generated by any means, you should try:
Re-Assign
If they are generated from PHP, and they contain string values, use the escaped quoting around each variables like this:
<?php
echo 'Re-Assign';
?>
The logic is similar to the updated code in the question, which generates code using JavaScript (maybe using jQuery?): don't forget to apply the escaped quotes to each variable:
var user = element.UserName;
var valuationId = element.ValuationId;
$('#ValuationAssignedTable').append('<tr> <td>Re-Assign </td> </tr>');
The moral of the story is
'someString(\''+'otherString'+','+'yetAnotherString'+'\')'
Will get evaluated as:
someString('otherString,yetAnotherString');
Whereas you would need:
someString('otherString','yetAnotherString');
Solution: Pass multiple arguments with onclick for html generated in JS
For html generated in JS , do as below (we are using single quote as
string wrapper).
Each argument has to wrapped in a single quote else
all of yours argument will be considered as a single argument like
functionName('a,b') , now its a single argument with value a,b.
We have to use string escape character backslash() to close first argument
with single quote, give a separator comma in between and then start next argument with a
single quote. (This is the magic code to use '\',\'')
Example:
$('#ValuationAssignedTable').append('<tr> <td>Re-Assign </td> </tr>');
$Name= "'".$row['Name']."'";
$Val1= "'".$row['Val1']."'";
$Year= "'".$row['Year']."'";
$Month="'".$row['Month']."'";
echo '<button type="button" onclick="fun('.$Id.','.$Val1.','.$Year.','.$Month.','.$Id.');" >submit</button>';
enclose each argument with backticks( ` )
example:
<button onclick="updateById(`id`, `name`)">update</button>
function updateById(id, name) {
alert(id + name );
...
}
Please try this
for static values--onclick="return ReAssign('valuationId','user')"
for dynamic values--onclick="return ReAssign(valuationId,user)"
That is because you pass string to the function. Just remove quotes and pass real values:
Re-Assign
Guess the ReAssign function should return true or false.
A few things here...
If you want to call a function when the onclick event happens, you'll just want the function name plus the parameters.
Then if your parameters are a variable (which they look like they are), then you won't want quotes around them. Not only that, but if these are global variables, you'll want to add in "window." before that, because that's the object that holds all global variables.
Lastly, if these parameters aren't variables, you'll want to exclude the slashes to escape those characters. Since the value of onclick is wrapped by double quotes, single quotes won't be an issue. So your answer will look like this...
Re-Assign
There are a few extra things to note here, if you want more than a quick solution.
You looked like you were trying to use the + operator to combine strings in HTML. HTML is a scripting language, so when you're writing it, the whole thing is just a string itself. You can just skip these from now on, because it's not code your browser will be running (just a whole bunch of stuff, and anything that already exists is what has special meaning by the browser).
Next, you're using an anchor tag/link that doesn't actually take the user to another website, just runs some code. I'd use something else other than an anchor tag, with the appropriate CSS to format it to look the way you want. It really depends on the setting, but in many cases, a span tag will do. Give it a class (like class="runjs") and have a rule of CSS for that. To get it to imitate a link's behavior, use this:
.runjs {
cursor: pointer;
text-decoration: underline;
color: blue;
}
This lets you leave out the href attribute which you weren't using anyways.
Last, you probably want to use JavaScript to set the value of this link's onclick attribute instead of hand writing it. It keeps your page cleaner by keeping the code of your page separate from what the structure of your page. In your class, you could change all these links like this...
var links = document.getElementsByClassName('runjs');
for(var i = 0; i < links.length; i++)
links[i].onclick = function() { ReAssign('valuationId', window.user); };
While this won't work in some older browsers (because of the getElementsByClassName method), it's just three lines and does exactly what you're looking for. Each of these links has an anonymous function tied to them meaning they don't have any variable tied to them except that tag's onclick value. Plus if you wanted to, you could include more lines of code this way, all grouped up in one tidy location.
function ReAssign(valautionId, userName) {
var valautionId
var userName
alert(valautionId);
alert(userName);
}
Re-Assign

Illegal Character error in jQuery - regardless of function content

First of all, I've done my research and I did find a bunch of simialr questions. However, I didn't find an answer that applies to my problem. All the examples I found were related to unescaped characters, single/double quote mishaps and the like. I on the other hand am getting this error on the following function:
$('.seq_input').blur(function(){
//var id = $(this).data('id');
//var index = parseInt($(this).val()),
//element = $("#test-list li").eq(id).remove();
//$("#test-list li").eq(index - 1).before(element); // -1 because users like 1 based indices
alert('what?');
})​​​;
As you see I commented out everything and just left an alert, and I'm still getting the error, pointing to the last line of the function. It couldn't have anything to do with other functions because I just added this one alone at the end of my current Javascript.
Can someone please tell me what's going on here? Why on Earth would a function that just alerts something (or even if it doesn't do anything) give an error?
NOTE: error is shown as soon as the page is loaded
There are invisible characters between the trailing semicolon and the parenthesis. I concatenated your code, put it in a string, and called a non-existent function in order to trigger a error (using this method).
'})​​​;'.l()
>>> TypeError: "})\u200B\u200B\u200B;".l is not a function
$('.seq_input') may used on the other functions, try using new id to do that function.

Replacing c# function bij Jquery not working without knowing how to troubleshoot

I'm trying to replace an ASP.NET (C#) server-sided method by an javascript/Jquery method. I'm fairly new to Jquery but all went well until I began with regular expressions.
my code in ASP.NET C#
if ((Regex.Match(postcode.Trim(), #"^[1-9]\d{3} ?[a-zA-Z]{2}$")).Success)
{
return Regex.Replace(postcode.Trim(), #"(^[1-9]\d{3})( ?)([a-zA-Z]{2}$)", "$1$3").ToUpper();
}
else
{
throw new Exception("Postcode incorrect");
}
in Jquery I'm only focussing to replace for the moment by manually input the right strings.
I've created a function like:
function FormatDutchPostalCode() {
var postcode = $("#Text1").val();
postcode = postcode.replace(/(^[1-9]\d{3})( ?)([a-zA-Z]{2}$)/, $1$3);
$("#Text1").val(postcode);
}
I'm getting the value from the textbox, so far so good. But when replacing it seems the browsers exits the function (tested in IE9 and FF10.0.1)
What I'm i doing wrong and is it possible to troubleshoot Jquery/Javascript. I've seen firebug could set breakpoints but I can't find if (and if so which) errors occur.
Here is a port of your C# function to JS. It uses an IIFE in order to cache the regex without polluting the current execution scope.
jsFiddle
var FormatDutchPostalCode = (function() {
var reg = /^([1-9]\d{3})\s?([a-z]{2})$/i;
return function(){
var postcode = $.trim($("#Text1").val());
if (postcode && postcode.match(reg) )
{
return postcode.replace(reg, "$1$2").toUpperCase();
}
else
{
throw new Error("Postcode incorrect");
}
};
}());
You need to use '$1$3' or /$1$3/ for the replacement pattern. Currently you've placed the replacement pattern in without using it as a string or regex pattern.
Check out this jsFiddle link showing a working solution.
You could also simplify your pattern by removing the capture group for the optional space, then you can perform the replace using the existing capture groups:
Pattern: /^([1-9]\d{3}) ?([a-zA-Z]{2})$/
Replacement: '$1$2' (only 2 groups exist)
To use Firebug or developer tools, you should be able to bring the tool up using the F12 key. You can test your replacement directly in the console window, or debug your script from the script tab (select the relevant JavaScript file) and place a breakpoint on the line you're interested in by right clicking and adding it or clicking on the line number on the left.
Check out this article for more details: JavaScript debugging for beginners.

escape() doesn't seem to work consistently?

using javascript, I generate HTML code, for example adding an function which starts by clicking a link, like:
$('#myDiv').append('click');
So start() should be called if somebody hits the link (click).
TERM could contain a single word, like world or moody's, the generated HTML code would look like:
click
OR
click
As you can see, the 2nd example will not work. So i decided to "escape" the TERM, like so:
$('#myDiv').append('click');
Looking at the HTML source-code using firebug, is see, that the following code was generated:
click
Thats works fine, until I really click the link - so the browser (here firefox) seams to interpret the %27 and tries to fire start('moody's');
Is there a way to escape the term persistent without interpreting the %27 until the term is handled in JS? Is there an other solution instead of using regular expressions to change ' to \'?
Don't try to generate inline JavaScript. That way lies too much pain and maintenance hell. (If you were to go down that route, then you would escape characters in JavaScript strings with \).
Use standard event binding routines instead.
Assuming that $ is jQuery, and not one of the many other libraries that use that unhelpful variable name:
$('#myDiv').append(
$('<a>').append("click").attr('href', 'A sensible fallback').click(function (e) {
alert(TERM); // Because I don't have the function you were calling
e.preventDefault();
})
);
See also http://jsfiddle.net/TudEw/
escape() is used for url-encoding stuff, not for making it possible to put in a string literal. Your code is seriously flawed for several reasons.
If you want an onclick event, use an onclick event. Do not try to "inject" javascript code with your markup. If you have the "string" in a variable, you should never need to substitute anything in it unless you are generating urls or other restricted terms.
var element = $('<span>click</span>');
element.bind('click', function () { start(TERM); });
$('#myDiv').append(element);
If you don't know what this does, then go back to basic and learn what events and function references in javascript means.
That escape() function is for escaping url's for passing over a network, not strings. I don't know that there's a built-in function to escape strings for JavaScript, but you can try this one I found online: http://www.willstrohl.com/Blog/EntryId/67/HOW-TO-Escape-Single-Quotes-for-JavaScript-Strings.
Usage: EscapeSingleQuotes(strString)
Edit: Just noticed your note about regular expressions. This solution does use regular expressions, but I think there's nothing wrong with that :-)

Categories

Resources