# Hack g-code.js parser

Here you can see g-code parser, written in JavaScript to use in microcontroller (like espruino). But you can run it in browser, because it don't use any specific features.

function gcode(str){
//Removes comment, parses command name and args
const [,f,args] = (str.match(/^([GM]\d+) ([^;]+)/) || [,"",""]);
//A1.2 B43 C -> {A: 1.2, B: 42, C: 0}
eval(f+"({"+args.replace(/(\w)([\d\.]*)/g,"$1:$2+0,")+"})");
}
const G1 = console.log;
gcode(prompt("crackme"));

When you pass G1 X3 Y4.53 Z42 to gcode(), it runs G1({X: 3, Y: 4.53, Z: 42}). As you can see, it uses eval, protected by regexp. But despite of this, you can attack this function and cause remote code execution. Your goal is to run alert("pwned"). This is code golf, so shortest working input wins

• Is alertpwned  fine? – l4m2 Oct 29 '18 at 11:22
• I suggest editing the post to say [[your goal is to display a dialog box with the text "pwned", as if alert("pwned") was run]]. – user202729 Oct 29 '18 at 14:39
• @l4m2 if it opens box with "pwned" – Евгений Новиков Oct 29 '18 at 19:01

# 112 bytes

G1 $:(ƒ=(Τ,$=+[])=>Τ[$]?Τ[$]+ƒ(Τ,++$+'5'[+[]]*(Τ[$]==':')):'')[ƒ('constructor')](ƒ('alert("pwned")'))()


function gcode(str){
//Removes comment, parses command name and args
const [,f,args] = (str.match(/^([GM]\d+) ([^;]+)/) || [,"",""]);
//A1.2 B43 C -> {A: 1.2, B: 42, C: 0}
eval(f+"({"+args.replace(/(\w)([\d\.]*)/g,"$1:$2+0,")+"})");
}
const G1 = console.log;

payload = G1 $:(ƒ=(Τ,$=+[])=>Τ[$]?Τ[$]+ƒ(Τ,++$+'5'[+[]]*(Τ[$]==':')):'')[ƒ('constructor')](ƒ('alert("pwned")'))();
gcode(payload);

• Each ƒ (U+0192), Τ (U+03A4) cost 2 bytes, they are not as same as ASCII f, T.

The gcode function will keep any /\W/ characters as is. So, we just need to use these characters to write some logic here. The idea is basically based on how JSF**k works. We construct the codes like this:

(()=>{})["constructor"]('alert("pwned")')


We need string literal "constructor" and alert("pwned"). But gcode convert "constructor" to "c: +0,o: +0,n: +0,....r: +0". So we need to convert the string back. We use this function to do the convert:

ƒ=(Τ,$=+[])=>Τ[$]?Τ[$]+ƒ(Τ,++$+'5'[+[]]*(Τ[$]==':')):''  Τ is the text inputed,$ is index. We first initialize $ to 0 using +[]. Then we output the character at the index position, and check if next character is ":", if so we skip the following 5 characters. Thanks to l4m2, saves few bytes. • Use $=>$ instead? – l4m2 Oct 29 '18 at 8:30 • +'5'[+[]]? – l4m2 Oct 29 '18 at 8:52 • @l4m2 +'5' will convert to string which is incorrect. – tsh Oct 29 '18 at 9:00 • I was thinking -~-~-~-~-~$ instead of $-~'4'[+[]] but it turns out to be the same length. – Neil Oct 29 '18 at 9:11 • @Neil changed to ++$+'5'[+[]]*(ß[\$]==':') anyway – tsh Oct 29 '18 at 9:16