I would like to ask what does mean this:
document:HideContent('content1');
I can't find any explanation why function HideContent defined as regular function is called with colon (":") instead of dot "." as usual.
Does this have any special meaning? Or dos it have some features?
That syntax can only possibly be a label. It's creating the label document and then executes one statement within it (HideContent()). Since the label isn't used within any loop construct by the author, it's pointless.
I suspect the author of the code doesn't really know Javascript and wanted to do something like call HideContent in the "global scope", but found document.HideContent to not work and pounded on the code until it stopped throwing errors. That the result is rather nonsensical and doesn't actually do what they thought it does didn't occur to them. This will work exactly the same when you simply omit document:.
(BTW, the "global scope" resolution would correctly be window.HideContent().)
Related
I am investigating defending against various types of attacks and I've found one I don't quite understand.
I have the following html:
<body onload="foo(''/alert(/Gotcha/)/'');">
<script>
function foo(){
alert("Inside Foo");
}
</script>
</body>
</html>
If you run this, you'll see an alert that says "/Gotcha/" followed immediately by one that says "Inside Foo".
What's going on? Why is the alert in the argument (that foo doesn't even have) running?
What's more, if I remove any of those slashes or single-quotes in the argument, it doesn't work.
if I change it to
<body onload="foo('/alert(/Gotcha/)/');">
All I get is "Inside Foo".
if I change it to
<body onload="foo('/alert(Gotcha)/');">
or remove any of the /s I don't get anything.
What is it about the ' and the / that makes this work?
We have a complicated expression there so let's break it up:
foo(''/alert(/Gotcha/)/'');
JS interprets this as a call to a function foo with ''/alert(/Gotcha/)/'' as a parameter (functions in JS do not have hard params, you can send as many as you'd like, even if the function declaration does not specify them)
The parameter is evaluated as the string '' followed by the division character /, followed by the alert function, then another division and another empty string
The parameter for the alert is evaluated since it's not a string, but a regular expression and the string representation is, incidentally, the same as the input regular expression string
The alert is executed with the string representation of the regex to evaluate the parameter for foo and the result of the whole parameter expression is NaN because the strings aren't divisible which doesn't really matter since the function foo does not use it
The function foo is executed.
The reason the argument in the foo call runs is because it is being interpreted as JavaScript. The arguments you are passing in foo(''/alert(/Gotcha/)/'' is essentially 2 strings and in the middle of them is a alert call.
Function arguments are all evaluated before the function is called. So when you write:
foo(alert('/Gotcha/'));
it first evaluates alert('/Gotcha/'), which causes /Gotcha/ to be displayed. Then the return value of alert() is passed as a parameter to foo(). foo() ignores its parameter, but that doesn't matter for the first step.
When you change it to
foo('/alert(/Gotcha/)/');
then the argument is a literal string, not a function call. So evaluating it just returns the string contents, it doesn't call the alert() function.
I can't see any reason why
<body onload="foo('/alert(Gotcha)/');">
would behave any differently from
<body onload="foo('/alert(/Gotcha/)/');">
so I suspect that your actual code has a typo that you didn't copy here. Check your Javascript console for syntax error messages.
Q: "Javascript functions embedded in arguments run automatically?"
A: It has nothing to do with function arguments. The foo function is there to simply add to the confusion of an already obfuscated expression. This is a simply a complicated way of writing an equivalent of:
onload="alert(/Gotcha/)"
which wants to alert the content of /Gotcha/ regex literal.
The regex literal provided in the string of the body onload assignment is simply the passive value of the alert function provided in that same string and has no share in what's going on there.
Everything else is simply a clever way of masking a simple assignment such as the above given onload="alert(/Gotcha/)" line of code.
The only thing that makes it work is the fact that inline event assignments are strings that need to get evaluated in order to get executed.
Therefore eval( ''/alert(/Gotcha/)/'' ) will do the same. Or putting it all back in its original form: eval( "foo(''/alert(/Gotcha/)/'');" ).
So yes, it is possible to execute any kind of string content assigned inline to an element event. But then, so is the setTimeout("foo(''/alert(/Gotcha/)/'');", 1000) capable of doing exactly the same.
So, "no" it has nothing to do with function arguments, but with the parsing of string content to the inline event of document body element.
EDIT:
Inline JavaScript on strings containing html for Images is (for the reasons explained above on why that Gotcha alert works) the most dangerous code injection without the need of user input. That's because image elements can handle onerror events, to which any arbitrary block of code can be executed, as in:
<img
src="http://Idontexist.com/wrongfolder/missingimage.jpg"
onerror="your arbitrary, but well written (malicious) code here!"
>
I recently had an issue with some javascript that goes against every bone of my programming background. Javascript does this often to me, so I'm not that surprised.
I have a function as such...
function x(param1, booleanParam, arrayParam){
....
}
I was getting a runtime error saying that arrayParam.length was not defined. On debugging I saw this was true and went to find out why. Turns out I had forgotten a comma in my function call as such...
x(param1, true [arrayJunk]);
The problem I'm having is figuring out why this call was made at all? Why isn't this a compile error, how does Javascript see this and think, "Yeah, that seems like it might work!"
Thanks in advance for any enlightenment you can share!
That's an indexing expression.
It's the same syntax as someArray[someIndex].
It will end up passing undefined as the second parameter too, unless arrayJunk happens to be the name of a property of boolean primitives.
What happens is the following:
JavaScript engine converts true into a Boolean object (not the primitive)
It then tries to access the property name stored in arrayParam from that object
Property doesn't exist, so it returns undefined
If arrayParam was the string "toString", it would return a function object
In this case the expression was being interpreted as an index. Essentially the same as
someArray[42]
So it was being seen as a function call with 2 parameters instead of 3
Many dynamic languages don't check if you pass too many or too few arguments to a function.
While this can sometimes mask errors, it also allows you to roll your own defalut parameter scheme.
'onhashchange'in(window)
Having in() work is not a surprise, as new(XMLHTTPRequest) or typeof(x) are other examples of this construct, but not having to separate the string and in is.
Is this per ECMAScript specs? It works in Chrome and FF, haven't tested IE.
From what I can tell, there's no difference whether you wrap window in parenthesis or not in this particular instance. Either way, it checks for this member on the window object.
Might be less confusing if you use spaces:
'onhashchange' in (window)
The same as
'onhashchange' in window
in is not a function, but when you remove the spaces I can see how you read it as such. One advantage to wrapping window in parenthesis is that you can then minify the code:
'onhashchange'in(window)
Something you could not do without the parenthesis.
' is a token that ends a string, so a pair of '' are semantically unambiguous, you don't need whitespace after the end of a string for the lexer to know that it has reached the end of a string.
Another way of saying that is that this works for the same reason that 'Hello '+'world' works.
Additionally, in is a keyword, not a function. It seems like you're thinking of () as the "function call operator", but in this case it's just a disambiguating parentheses.
It's like asking "why does 1 +(2) work?" + doesn't become a function just because you follow it with a paren, and similarly the following will work:
function foo(){}
foo
();
Javascript is brittle with its whitespace rules.
I'm not sure if the notation is confusing you (that maybe in() is a method?), but in is one of those elements of JS that few people correctly understand (I didn't really understand it until quite recently). This is a simplified version showing what in does:
var foo = {
'bar':1,
'barbar':2
}
console.log('bar' in foo); //true
console.log('baz' in foo); //false
What makes this all the more confusing is that you can use in inside a for() loop, as if it (in) were an iterator. The way I tend to think of for loops is like this:
for (exp1; condition; exp2) {
/* statements */
}
for (condition) {
/* statements */
}
In other words, the loop will continue until the in condition fails, which will happen when it runs out of members.
I was reading In JavaScript, what is the advantage of !function(){}() over (function () {})()? then it hit me, why use :
(function(){})() or !function(){}() instead of just function(){}()?
Is there any specific reason?
It depends on where you write this. function(){}() by itself will generate a syntax error as it is evaluated as function declaration and those need names.
By using parenthesis or the not operator, you enforce it to be interpreted as function expression, which don't need names.
In case where it would be treated as expression anyway, you can omit the parenthesis or the operator.
I guess you are asking why use:
var fn = (function(){}());
versus:
var fn = function(){}();
The simple answer for me is that often the function on the RHS is long and it's not until I get to the bottom and see the closing () that I realise I've been reading a function expression and not a function assignment.
A full explanation is in Peter Michaux's An Important Pair of Parens.
A slight variation on RobG's answer.
Many scripts encompass the entire program in one function to ensure proper scoping. This function is then immediately run using the double parentheses at the end. However, this is slightly different then programs which define a function that can be used in the page but not run initially.
The only difference between these two scenarios is the last two characters (the addition of the double parentheses). Since these could be very long programs, the initial parenthesis is there to indicate that "this will be run immediately."
Is it necessary for the program to run? No. Is it helpful for someone looking at the code and trying to understand it? Yes.
I am trying to understand how to "chain" JavaScript events together like jQuery does. I found a question here on S.O. that was similar to my goal, but I do not understand the code in the answer.
Code Source
(function( window, undefined ) {
...etc...
}(window)
What does that mean? What is it doing? It reminds me of Jquery's $(document).ready(){} function, but I don't know why this person wrapped his code in this anonymous function that passes window and undefined.
My ultimate goal is to figure out how to execute methods on an object by chaining methods together like jQuery. I know that jQuery already does this but I am looking into this primarily for growth as a developer.
It defines a function (using a function operator as opposed to a function statement). The parenthesis around it ensure that it is treated as the operator rather than the statement.
It then executes it immediately, passing window as an argument.
Essentially, this is the same as:
var myFunction = function( window, undefined ) {
...etc...
};
myFunction(window);
… but without the interstitial variable.
This has nothing to do with jQuery style function chaining, where each method effectively ends with return this (so calling a method on the return value of another method is the same as calling it on the original object).
When a function is called with fewer arguments than its signature contains, the trailing arguments are assigned the value undefined.
So the above is a roundabout way of getting hold of the undefined value even if some lunatic has redefined it by saying var undefined= 'hello';. (This is illegal anyway in ECMAScript Fifth Edition's ‘strict mode’, but JavaScript coders do some weird things sometimes.)
There isn't really a good reason for passing in window like this though... the traditional way to get window if you can't rely on window is to call a function directly and use this.
Either way, this is simply defensive coding against pathological author JavaScript. It's not something you should worry about whilst writing your own code (in any case there's no way you can stop every way someone might mess up their JS environment), and it's nothing to do with chaining.