googleprojectzero / fuzzilli

A JavaScript Engine Fuzzer
Apache License 2.0
1.88k stars 305 forks source link

FuzzILTool Error #399

Open anansi2safe opened 1 year ago

anansi2safe commented 1 year ago

I have a JavaScript file:

let a = function() {
    return {}
 };

  for (let j = 0; j < 999; j++) {
    ((a = class b3 {[{c: eval()}]}) => {})();
    if (j == 8) {
      a();
    }
  }

I want to compile it into a .fzil file, but I encountered an error:

>swift run -c release FuzzILTool --compile ./tmp/tmp.js 
Building for production...
Build complete! (0.18s)
Failed to parse ./tmp/tmp.js: parsingFailed("\n/home/fuzzer/myspace/tools/fuzzilli/.build/x86_64-unknown-linux-gnu/release/Fuzzilli_Fuzzilli.resources/Parser/parser.js:19\n            throw \"Assertion failed\";\n            ^\nAssertion failed\n(Use `node --trace-uncaught ...` to show where the exception was thrown)\n")

When I remove the line ((a = class b3 {[{c: eval()}]}) => {})();, it compiles successfully. However, I cannot remove this line.

saelo commented 1 year ago

Thanks for the report! This looks like the parser is failing, could you run it manually and check where/why it fails: node --trace-uncaught Sources/Fuzzilli/Compiler/Parser/parser.js Sources/Fuzzilli/Protobuf/ast.proto path/to/code.js /tmp/ast.proto?

anansi2safe commented 1 year ago

Thanks for the report! This looks like the parser is failing, could you run it manually and check where/why it fails: node --trace-uncaught Sources/Fuzzilli/Compiler/Parser/parser.js Sources/Fuzzilli/Protobuf/ast.proto path/to/code.js /tmp/ast.proto?

>node --trace-uncaught Sources/Fuzzilli/Compiler/Parser/parser.js Sources/Fuzzilli/Protobuf/ast.proto ./tmp/tmp.js /tmp/ast.proto

/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:19
            throw "Assertion failed";
            ^
Assertion failed
Thrown at:
    at assert (/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:19:13)
    at visitParameter (/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:76:9)
    at visitExpression (/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:482:46)
    at visitExpression (/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:493:30)
    at visitStatement (/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:119:28)
    at visitStatement (/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:114:31)
    at visitStatement (/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:264:32)
    at visitProgram (/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:51:37)
    at parse (/home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:561:12)
    at /home/fuzzer/myspace/tools/fuzzilli/Sources/Fuzzilli/Compiler/Parser/parser.js:570:15
saelo commented 1 year ago

Ah right, so probably the reason is that the parser doesn't currently support parameters with default values: https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/Compiler/Parser/parser.js#L76 (you could dump(param) before that assert to confirm that it's the a parameter).

I don't think we'll get around to implementing that anytime soon, but we'll be very happy to take PRs. The first step would be to add support for default parameters in the ast.proto definition and support them in parser.js. Then Compiler.swift will need to handle them here, by compiling the default value to a FuzzIL variable, and probably for a start just assigning them to the parameter value if it is undefined inside the function body, so the JS would then look like this:

function foo(a) {
    if (typeof a === 'undefined') {
       a = <default value>;
    }
    ...
}

Finally, to be able to lift back to default arguments (function foo(a = <default value>) { ... }, we'll need to implement default parameters in FuzzIL. It'd probably look something like this: https://github.com/googleprojectzero/fuzzilli/pull/301

areuu commented 1 year ago

I have a JavaScript file:

let a = function() {
    return {}
 };

  for (let j = 0; j < 999; j++) {
    ((a = class b3 {[{c: eval()}]}) => {})();
    if (j == 8) {
      a();
    }
  }

I want to compile it into a .fzil file, but I encountered an error:

>swift run -c release FuzzILTool --compile ./tmp/tmp.js 
Building for production...
Build complete! (0.18s)
Failed to parse ./tmp/tmp.js: parsingFailed("\n/home/fuzzer/myspace/tools/fuzzilli/.build/x86_64-unknown-linux-gnu/release/Fuzzilli_Fuzzilli.resources/Parser/parser.js:19\n            throw \"Assertion failed\";\n            ^\nAssertion failed\n(Use `node --trace-uncaught ...` to show where the exception was thrown)\n")

When I remove the line ((a = class b3 {[{c: eval()}]}) => {})();, it compiles successfully. However, I cannot remove this line.

老哥机智,ddw

anansi2safe commented 11 months ago

Hi, has this issue been fixed?

Ah right, so probably the reason is that the parser doesn't currently support parameters with default values: https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/Compiler/Parser/parser.js#L76 (you could dump(param) before that assert to confirm that it's the a parameter).

I don't think we'll get around to implementing that anytime soon, but we'll be very happy to take PRs. The first step would be to add support for default parameters in the ast.proto definition and support them in parser.js. Then Compiler.swift will need to handle them here, by compiling the default value to a FuzzIL variable, and probably for a start just assigning them to the parameter value if it is undefined inside the function body, so the JS would then look like this:

function foo(a) {
    if (typeof a === 'undefined') {
       a = <default value>;
    }
    ...
}

Finally, to be able to lift back to default arguments (function foo(a = <default value>) { ... }, we'll need to implement default parameters in FuzzIL. It'd probably look something like this: #301