From: Oleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) Date: Wed, 13 Jul 2022 14:23:17 +0000 (+0000) Subject: Pull request #3509: JS_Norm: distinct arrow functions handling X-Git-Tag: 3.1.36.0~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2fbfe5023a4d688d66800170a5e02c7d0e1f1b88;p=thirdparty%2Fsnort3.git Pull request #3509: JS_Norm: distinct arrow functions handling Merge in SNORT/snort3 from ~ASERBENI/snort3:arrow_scope to master Squashed commit of the following: commit fa93f3dd0ff971447de8b2d85876b514a33dee85 Author: Andrii Serbeniuk Date: Mon Jul 11 15:31:19 2022 +0300 utils: fix arrow functions parsing --- diff --git a/src/utils/js_tokenizer.h b/src/utils/js_tokenizer.h index f0a16027a..fd985c6c8 100644 --- a/src/utils/js_tokenizer.h +++ b/src/utils/js_tokenizer.h @@ -83,9 +83,10 @@ private: enum ScopeMetaType { NOT_SET = 0, - FUNCTION, // function, arrow function - BLOCK, // if, else, for, while, do, with, switch, try, catch, finally, block of code - OBJECT, // object definition, class definition + ARROW_FUNCTION, // arrow function + FUNCTION, // function + BLOCK, // if, else, for, while, do, with, switch, try, catch, finally, block of code + OBJECT, // object definition, class definition SCOPE_META_TYPE_MAX }; enum FuncType diff --git a/src/utils/js_tokenizer.l b/src/utils/js_tokenizer.l index 26b9df90b..45a4bcb87 100644 --- a/src/utils/js_tokenizer.l +++ b/src/utils/js_tokenizer.l @@ -1352,6 +1352,7 @@ static std::string unescape_unicode(const char* lexeme) const char* JSTokenizer::p_scope_codes[] = { "invalid", + "arrow function", "function", "block", "object", @@ -1863,6 +1864,7 @@ JSTokenizer::JSRet JSTokenizer::scope_push(ScopeType t) break; } + case ScopeMetaType::ARROW_FUNCTION: break; case ScopeMetaType::BLOCK: break; case ScopeMetaType::NOT_SET: break; default: assert(false); return BAD_TOKEN; @@ -2045,6 +2047,7 @@ JSProgramScopeType JSTokenizer::m2p(ScopeMetaType mt) { switch (mt) { + case ScopeMetaType::ARROW_FUNCTION: case ScopeMetaType::FUNCTION: return JSProgramScopeType::FUNCTION; case ScopeMetaType::BLOCK: @@ -2549,7 +2552,7 @@ JSTokenizer::JSRet JSTokenizer::punctuator_arrow() set_ident_norm(true); if (meta_type() == ScopeMetaType::NOT_SET) { - set_meta_type(ScopeMetaType::FUNCTION); + set_meta_type(ScopeMetaType::ARROW_FUNCTION); EXEC(p_scope_push(meta_type())) } return EOS; diff --git a/src/utils/test/js_normalizer_test.cc b/src/utils/test/js_normalizer_test.cc index 5b44df3e0..d6709f6bc 100644 --- a/src/utils/test/js_normalizer_test.cc +++ b/src/utils/test/js_normalizer_test.cc @@ -4769,6 +4769,9 @@ TEST_CASE("Scope tracking - basic","[JSNormalizer]") SECTION("Function scope - arrow function without scope") test_scope("var f = (a,b)=> a",{GLOBAL,FUNCTION}); + SECTION("Function scope - function call in an arrow function without scope") + test_scope("var f = (a,b)=> call(",{GLOBAL,FUNCTION}); + SECTION("Function scope - method in object initialization") test_scope("var o = { f(){",{GLOBAL,BLOCK,BLOCK}); @@ -4917,6 +4920,9 @@ TEST_CASE("Scope tracking - closing","[JSNormalizer]") SECTION("Function scope - arrow function without scope") test_scope("var f = (a,b)=>a;",{GLOBAL}); + SECTION("Function scope - function call in an arrow function without scope") + test_scope("var f = a=>call();",{GLOBAL}); + SECTION("Function scope - arrow function as a function parameter") test_scope("console.log(a=>c)",{GLOBAL}); diff --git a/src/utils/test/js_unescape_test.cc b/src/utils/test/js_unescape_test.cc index 0df3e2c34..3b8cdb58a 100644 --- a/src/utils/test/js_unescape_test.cc +++ b/src/utils/test/js_unescape_test.cc @@ -1217,5 +1217,24 @@ TEST_CASE("Internal limits", "[JSNormalizer]") } } +TEST_CASE("Function type detection", "[JSNormalizer]") +{ + SECTION("in arrow function") + { + test_normalization( + "var func = () => unescape('%62%61%72');" + "func = () => String.fromCodePoint(0x0062, 0x0061, 0x0072);" + "func = () => String.fromCharCode(0x0062, 0x0061, 0x0072);" + "func = () => decodeURIComponent('%62%61%72');" + "func = () => decodeURI('%62%61%72');", + "var var_0000=()=>'bar';" + "var_0000=()=>'bar';" + "var_0000=()=>'bar';" + "var_0000=()=>'bar';" + "var_0000=()=>'bar';" + ); + } +} + #endif // CATCH_TEST_BUILD