Node.js SyntaxError: Invalid or unexpected token (but its weird) - javascript

I have never seen this error in my life
?
And I just found it so odd...
My code here is seen like this:
const no = require('noparenth');
(at index.js:1)
and I have literally never seen this in my life...
the library in question is one that just allows you to invoke a function without parenthesis. I made it so it would make it easier to code + make it faster.
the code is as seen here:
Function.prototype.valueOf = function() {
this.call(this);
return 0;
};
Thats it...
actual error:
C:\Users\summit\testing\index.js:1
��c
SyntaxError: Invalid or unexpected token

One possible way to get that type of characters is to save a file as UTF-16 LE and load it as if it were UTF-8.
If you use PowerShell, it's easy to produce a file in UTF-16 LE encoding, for example if you run echo "" > index.js. If you open the resulting file in VSCode, you can see at the bottom right that it's UTF-16 LE.
Note that the resulting file is not really empty, and you can verify that by inputting require('fs').readFileSync('index.js') in the Node.js REPL.
You'll get <Buffer ff fe 0d 00 0a 00> which, when interpreted in UTF-16 LE, consists of byte order mark (U+FEFF), carriage return (U+000D) and new line character (U+000A).
Even if you open that file with a text editor and replace everything with your text, the byte order mark will still be there (as long as you still save in UTF-16 LE). For example, if you save const x = 0 the buffer will become like ff fe 63 00 ..., notice that the ff fe still is there.
When a program attempts to load it as UTF-8, it will get <invalid character> <invalid character> c <null character> and so on.
What you're seeing in the output is exactly from <invalid character> <invalid character> c (Unicode: U+FFFD U+FFFD U+0063), obviously not a valid token in Node.js.
As for your actual function, it will only be invoked when you have type coercions (like +myFunction or myFunction + "") or if you directly call it like myFunction.valueOf().
And I expect it to make it (slightly) slower, because it calls a user-defined function rather than just native code.
And apart from the bad idea of modifying prototypes of objects you don't own, there is limited usefulness (if any) to this.
The this.call(this) means that you can't add more arguments to the function call.
Also, it's like myFunction.call(myFunction), I'm not sure why you would want to do that. And when used on a method of an object, it's like myObject.myMethod.call(myObject.myMethod) (with this equal to the function itself) rather than myObject.myMethod.call(myObject)
And it will break things that depend on the behavior of myFunction + "" etc.
It seems not that easy to find an example, nevertheless I found this example :
isNative(Math.sin) was originally supposed to return true, but after modifying the prototype the way shown above, it became 3

Related

Different ascii value between Safari and Chrome

Using macOS with BigSur version 11.4.
A file name on my mac called: второй
If i copy and paste the file name to chrome console and print "второй".charCodeAt(5) - 1080
Is Safari: "второй".charCodeAt(5) - 1081
This causes some discrepancies in my app.
Is there a way to handle this so both browsers will act the same?
There are (at least) two ways to write that word in Unicode: второй (as in your question), which uses a и (U+0438) followed by the combining character for the mark (U+0306); and второй, which uses a single code point (U+0439) that is the combination of those (й). The one using a separate letter and combining mark is in normalization form D ("canonical decomposed," in which separate code points with combining marks are used where possible), and the one using the combined code point is in normalization form C ("canonical composed," in which combined code points are used where possible).
So for whatever reason, on Safari your string (in form D) is getting normalized to form C, but not on Chrome.
To ensure you're dealing with the same sequence of code points, you can normalize the string using the normalize method (ES2015+). It defaults to NFC, but you can pass it "NFD" if you want NFD:
const original = "второй";
console.log("original:", original.length, original.charCodeAt(5));
const nfc = original.normalize(); // Defaults to "NFC"
console.log("NFC:", nfc.length, nfc.charCodeAt(5));
const nfd = nfc.normalize("NFD");
console.log("NFD:", nfd.length, nfd.charCodeAt(5));
Note that charCodeAt works in UTF-16 code units, not code points (post on my blog about the difference), although it happens that in your example all of the code points are represented by a single code unit. You can use codePointAt to look at code points instead, although (again) in this particular case it doesn't make a difference.

JSON.stringify and "\u2028\u2029" check?

Sometimes I see in a view source page ( html view source) this code:
if (JSON.stringify(["\u2028\u2029"]) === '["\u2028\u2029"]') JSON.stringify = function (a) {
var b = /\u2028/g,
c = /\u2029/g;
return function (d, e, f) {
var g = a.call(this, d, e, f);
if (g) {
if (-1 < g.indexOf('\u2028')) g = g.replace(b, '\\u2028');
if (-1 < g.indexOf('\u2029')) g = g.replace(c, '\\u2029');
}
return g;
};
}(JSON.stringify);
What is the problem with JSON.stringify(["\u2028\u2029"]) that it needs to be checked ?
Additional info :
JSON.stringify(["\u2028\u2029"]) value is "["

"]"
'["\u2028\u2029"]' value is also "["

"]"
I thought it might be a security feature. FileFormat.info for 2028 and 2029 have a banner stating
Do not use this character in domain names. Browsers are blacklisting it because of the potential for phishing.
But it turns out that the line and paragraph separators \u2028 and \u2029 respectively are treated as a new line in ES5 JavaScript.
From http://www.thespanner.co.uk/2011/07/25/the-json-specification-is-now-wrong/
\u2028 and \u2029 characters that can break entire JSON feeds since the string will contain a new line and the JavaScript parser will bail out
So you are seeing a patch for JSON.stringify. Also see Node.js JavaScript-stringify
Edit: Yes, modern browsers' built-in JSON object should take care of this correctly. I can't find any links to the actual source to back this up though. The Chromium code search doesn't mention any bugs that would warrant adding this workaround manually. It looks like Firefox 3.5 was the first version to have native JSON support, not entirely bug-free though. IE8 supports it too. So it is likely a now unnecessary patch, assuming browsers have implemented the specification correctly.
After reading both answers , here is the Simple visual explanation :
doing this
alert(JSON.stringify({"a":"sddd\u2028sssss"})) // can cause problems
will alert :
While changing the trouble maker to something else ( for example from \u to \1u)
will alert :
Now , let's invoke the function from my original Q ,
Lets try this alert(JSON.stringify({"a":"sddd\u2028sssss"})) again :
result :
and now , everybody's happy.
\u2028 and \u2029 are invisible Unicode line and paragraph separator characters. Natively JSON.stringify method converts these codes to their symbolic representation (as JavaScript automatically does in the strings), resulting in "["

"]". The code you have provided does not let JSON to convert the codes to symbols and preserves their \uXXXX representation in the output string, i.e. returning "["\u2028\u2029"]".

Javascript regex match fails on actual page, but regex tests work just fine

I have a very specific problem concerning a regular expression matching in Javascript. I'm trying to match a piece of source code, more specifically a portion here:
<TD WIDTH=100% ALIGN=right>World Boards | Olympa - Trade | <b>Bump when Yasir...</b></TD>
The part I'm trying to match is boardid=106121">Olympa - Trade</a>, the part I actually need is "Olympa". So I use the following line of JS code to get a match and have "Olympa" returned:
var world = document.documentElement.innerHTML.match('/boardid=[0-9]+">([A-Z][a-z]+)( - Trade){0,1}<\/a>/i')[1];
the ( - Trade) part is optional in my problem, hence the {0,1} in the regex.
There's also no easier way to narrow down the code by e.g. getElementsByTagName, so searching the complete source code is my only option.
Now here's the funny thing. I have used two online regex matchers (of which one was for JS-regex specifically) to test my regex against the complete source code. Both times, it had a match and returned "Olympa" exactly as it should have. However, when I have Chrome include the script on the actual page, it gives the following error:
Error in event handler for 'undefined': Cannot read property '1' of null TypeError: Cannot read property '1' of null
Obviously, the first part of my line returns "null" because it does not find a match, and taking [1] of "null" doesn't work.
I figured I might not be doing the match on the source code, but when I let the script output document.documentElement.innerHTML to the console, it outputs the complete source code.
I see no reason why this regex fails, so I must be overlooking something very silly. Does anyone else see the problem?
All help appreciated,
Kenneth
You're putting your regular expression inside a string. It should not be inside a string.
var world = document.documentElement.innerHTML.match(/boardid=[0-9]+">([A-Z][a-z]+)( - Trade){0,1}<\/a>/i)[1];
Another thing — it appears you have a document object, in which case all this HTML is already parsed for you, and you can take advantage of that instead of reinventing a fragile wheel.
var element = document.querySelector('a[href*="boardid="]');
var world = element.textContent;
(This assumes that you don't need <=IE8 support. If you do, there remains a better way, though.)
(P.S. ? is shorthand for {0,1}.)

Javascript in LESS appears hobbled: workaround?

I am finding that LESS has a hobbled JavaScript evaluator, at least the way I am using it, which is to compile *.less files into *.css on a client before uploading them to the web server.
I'm aware that compilation may be more often done server-side, but for performance & simplicity we only want CSS files on the server. I'm compiling the LESS files on Fedora Linux with the lessc ruby gem installed into Node Package Manager as in these instructions.
The compiler is working perfectly, but as far as I can tell the JavaScript expression evaluation is sorely limited. I believe this also applies to server-side JavaScript expression evaluation based on this posting which suggests uncertainty about how the JavaScript engine is plugged into the LESS environment.
All I can use are simple, comma-separated expressions, like the following:
#bar: `
"ignored-string-expression"
,
5
`;
div.test-thing { content: ~"#{bar}"; }
which compiles into:
div.test-thing {
content: 5;
}
When I try to define a function, the compiler barfs (whether or not the semicolon in the expression is backslash-escaped):
[719] anjaneya% cat testfunc.less
#bar: `function foo() {return 5}; foo()`;
div.test-thing { content: ~"#{bar}"; }
[720] anjaneya% lessc testfunc.less
SyntaxError: JavaScript evaluation error: `function foo() {return 5}; foo()` ...
There also doesn't seem to be any way of looping, even if you try to trick it into evaluating a loop as you would the "ignored-string-expression" above, like:
#foo: `x = 0,
for (var n = 0; n <= 10; n++) { x++; },
x
`;
div.test-thing { content: ~"#{bar}"; }
which says:
ParseError: Syntax Error on line 1 ...
Why bother? To be able to compile this LESS:
#svgSource: '<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><linearGradient id="g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#{start}" /><stop offset="1" stop-color="#{end}" /></linearGradient><rect x="0" y="0" width="100%" height="100%" fill="url(#g)" /></svg>';
into this CSS:
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgeDE9IjAiIHkxPSIwIiB4Mj0iMCIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzU3OWRkYiIgLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDAwMjIiIC8+PC9saW5lYXJHcmFkaWVudD48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2cpIiAvPjwvc3ZnPg==);
using a program like this, whether the algorithm is implemented in JavaScript, PHP, Perl, UNIX shell, or anything else. This processing might be done without function definitions but not without looping, and without functions you can't even have recursion.
Given that both functions and looping are compound statements that probably aren't evaluated as expressions (it's not LISP), that is probably the basis for the failure... it's not really a full JavaScript interpreter. So I'm hoping someone who really knows the LESS compiler will:
clarify the limitation above, so I can use JavaScript & LESS portably for this task
say how this problem can be worked around (e.g., with a "shell escape" or any evaluation environment that can process strings iteratively) and/or
say how to extend the LESS compiler with such text processing capabilities, like a "real" JavaScript engine.
The data-uri() function is now built into LESS:
http://lesscss.org/functions/#misc-functions-data-uri
Will that help?
I think what you're looking for is both a mixture of a BUNCH of little frustrating things about using javascript in LESS.
All javascript has to be on one line. (I... don't even.. whatever.)
All javascript has to return something or you get the completely useless error "Cannot read property 'value' of undefined"
All javascript must be one statement. This comes from the original use case where they were thinking you would do something like #foo: ~'something.javascript.is.good.at({#bar});'
Number 1 is formatting, 2 just means you need to return something even if you don't use it, but number 3 catches a lot of people off guard. To get around it, just make you "one thing" a self-executing anonymous function.
Eg:
(function(){
do.some.cool.stuff();
other.cool.things();
return('Fry');
})();
So the LESS parser sees that (make sure it's all in one line instead of how I wrote it!), bundles it off to javascript land as a single execution, reads the return value, and calls it a day.
If you want to see it in action, I recently wrote LESS mixin to make RGBA 1x1 pixels for background fills, etc. that uses all of this madness.
Hope that helps!
I know this post is a couple of years old but javascript embedded in LESS can be very handy so I though I would post some tips:
//All javascript must
// a. be on the rhs of an assignment e.g. #x:` var x = #{val}+7`;
// b. must evaluate to a value
// c. cannot be terminated by a ';'
//
// To get around this, multiline code can be packed into an IIFE......
#val:7;
#loop:`(function(val){
var sum=0;
for(var i=0; i<val; i++){sum+=i;}
return sum;
} )(#{val})`;
.test{
content:#loop; // content: 21;
}
// console.log writes directly to the beginning of the output file
#x:`console.log('/*...... loop = #{loop}.......*/')`; // /*...... loop = 21.......*/
// you can use the global variable. Here we attach a library module to it.....
#x:`global.myLib={}`;
// Then add a method to the module..............
#btoa:`myLib.btoa=function(str){
var buffer = new Buffer((str).toString(), 'binary');
return buffer.toString('base64');
}`;
// And invoke the method to encode some text............................
#sometext:'LESS is more (more or less)';
.test2{
content:`myLib.btoa(#{sometext})`;// content: "TEVTUyBpcyBtb3JlIChtb3JlIG9yIGxlc3Mp";
}

__LINE__ equivalent in Javascript

Is there any way to get the source line number in Javascript, like __LINE__ for C or PHP?
There is a way, although more expensive: throw an exception, catch it immediately, and dig out the first entry from its stack trace. See example here on how to parse the trace. The same trick can also be used in plain Java (if the code is compiled with debugging information turned on).
Edit: Apparently not all browsers support this. The good news is (thanks for the comment, Christoph!) that some browsers export source file name and line number directly through the fileName and lineNumber properties of the error object.
The short answer is no.
The long answer is that depending on your browser you might be able to throw & catch an exception and pull out a stack trace.
I suspect you're using this for debugging (I hope so, anyway!) so your best bet would be to use Firebug. This will give you a console object; you can call console.trace() at any point to see what your programme is doing without breaking execution.
You can try to run C preprocessor (f.e. cpp from GNU Compiler Collection) on your javascript files -- either dynamically with each request or statically, by making this operation be applied every time you change your javascript files. I think the javascript syntax is similar enough for this to work.
Then you'd have all the power of C preprocessor.
You can use this in vanilla JS:
function getLine(offset) {
var stack = new Error().stack.split('\n'),
line = stack[(offset || 1) + 1].split(':');
return parseInt(line[line.length - 2], 10);
}
Object.defineProperty(window, '__LINE__', {
get: function () {
return getLine(2);
}
});
You will now have access to the global variable __LINE__
A __LINE__ in C is expanded by a preprocessor which literally replaces it with the line number of the current input. So, when you see
printf("Line Number: %d\r\n", __LINE__);
the compiler sees:
printf("Line Number: %d\r\n", 324);
In effect the number (324 in this case) is HARDCODED into the program. It is only this two-pass mechanism that makes this possible.
I do not know how PHP achieves this (is it preprocessed also?).
I think preprocessing makes more sense, in that it adds no runtime overhead. An alternative to the C preprocessor is using perl, as in the 2 step procedure below:
1 – add “Line # 999 \n” to each line in the script that you want numbered, e.g.,
alert ( "Line # 999 \n"+request.responseText);
2 – run the perl below:
cat my_js.js | perl -ane "{ s/Line # \d+ /Line # $. /; print $_;}" > C_my_js.js; mv C_my_js.js my_js.js
There is one workaround.
Usually the __ LINE __ combined with the __ FILE __ is used for marking a locations in code and the marking is done to find that location later.
However, it is possible to achieve the same effect by using Globally Unique Identifiers (GUID-s) in stead of the __ LINE __ and __ FILE __. Details of the solution reside in the COMMENTS.txt of a BSD-licensed toolset that automates the process.

Categories