Skip to content

Commit

Permalink
✨ feat: Enhance built-in object matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
caoccao committed May 12, 2024
1 parent da9094c commit fd346fe
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@
import com.caoccao.javet.swc4j.ast.expr.lit.Swc4jAstArrayLit;
import com.caoccao.javet.swc4j.ast.expr.lit.Swc4jAstObjectLit;
import com.caoccao.javet.swc4j.ast.interfaces.ISwc4jAst;
import com.caoccao.javet.swc4j.ast.interfaces.ISwc4jAstPat;
import com.caoccao.javet.swc4j.ast.interfaces.ISwc4jAstPropOrSpread;
import com.caoccao.javet.swc4j.ast.pat.Swc4jAstArrayPat;
import com.caoccao.javet.swc4j.ast.pat.Swc4jAstBindingIdent;
import com.caoccao.javet.swc4j.ast.stmt.Swc4jAstClassDecl;
import com.caoccao.javet.swc4j.ast.stmt.Swc4jAstFnDecl;
import com.caoccao.javet.swc4j.ast.stmt.Swc4jAstVarDeclarator;

import java.util.Optional;

Expand All @@ -49,8 +54,15 @@ public static JavetSanitizerBuiltInObjectMatcher getInstance() {
@Override
public ISwc4jAst matches(JavetSanitizerOptions options, ISwc4jAst node) {
switch (node.getType()) {
case AssignExpr:
case AssignExpr: // Entry
return matches(options, node.as(Swc4jAstAssignExpr.class).getLeft());
case ArrayPat:
for (Optional<ISwc4jAstPat> elem : node.as(Swc4jAstArrayPat.class).getElems()) {
if (elem.isPresent()) {
return matches(options, elem.get().as(ISwc4jAstPat.class));
}
}
break;
case ArrayLit:
for (Optional<Swc4jAstExprOrSpread> optionalExprOrSpread : node.as(Swc4jAstArrayLit.class).getElems()) {
if (optionalExprOrSpread.isPresent()) {
Expand All @@ -63,10 +75,25 @@ public ISwc4jAst matches(JavetSanitizerOptions options, ISwc4jAst node) {
break;
case BindingIdent:
return matches(options, node.as(Swc4jAstBindingIdent.class).getId());
case ClassDecl: // Entry
return matches(options, node.as(Swc4jAstClassDecl.class).getIdent());
case ExprOrSpread:
return matches(options, node.as(Swc4jAstExprOrSpread.class).getExpr());
case FnDecl: // Entry
return matches(options, node.as(Swc4jAstFnDecl.class).getIdent());
case Ident:
if (options.getBuiltInObjectSet().contains(node.as(Swc4jAstIdent.class).getSym())) {
String identifier = node.as(Swc4jAstIdent.class).getSym();
if (options.getReservedIdentifierMatcher().apply(identifier)) {
if (node.getParent() instanceof Swc4jAstFnDecl) {
if (!options.getReservedFunctionIdentifierSet().contains(identifier)) {
return node;
}
} else if (options.getReservedIdentifierSet().contains(identifier)) {
break;
} else if (!options.getReservedMutableIdentifierSet().contains(identifier)) {
return node;
}
} else if (options.getBuiltInObjectSet().contains(identifier)) {
return node;
}
break;
Expand All @@ -80,7 +107,8 @@ public ISwc4jAst matches(JavetSanitizerOptions options, ISwc4jAst node) {
}
}
break;
// TODO
case VarDeclarator: // Entry
return matches(options, node.as(Swc4jAstVarDeclarator.class).getName());
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ public Swc4jAstVisitorResponse visitAssignExpr(Swc4jAstAssignExpr node) {
return super.visitAssignExpr(node);
}

@Override
public Swc4jAstVisitorResponse visitClassDecl(Swc4jAstClassDecl node) {
validateBuiltInObject(options, node);
return super.visitClassDecl(node);
}

@Override
public Swc4jAstVisitorResponse visitDebuggerStmt(Swc4jAstDebuggerStmt node) {
if (!options.isKeywordDebuggerEnabled()) {
Expand Down Expand Up @@ -155,6 +161,12 @@ public Swc4jAstVisitorResponse visitExportNamespaceSpecifier(Swc4jAstExportNames
return super.visitExportNamespaceSpecifier(node);
}

@Override
public Swc4jAstVisitorResponse visitFnDecl(Swc4jAstFnDecl node) {
validateBuiltInObject(options, node);
return super.visitFnDecl(node);
}

@Override
public Swc4jAstVisitorResponse visitForOfStmt(Swc4jAstForOfStmt node) {
if (!options.isKeywordAwaitEnabled() && node.isAwait()) {
Expand Down Expand Up @@ -257,6 +269,12 @@ public Swc4jAstVisitorResponse visitVarDecl(Swc4jAstVarDecl node) {
return super.visitVarDecl(node);
}

@Override
public Swc4jAstVisitorResponse visitVarDeclarator(Swc4jAstVarDeclarator node) {
validateBuiltInObject(options, node);
return super.visitVarDeclarator(node);
}

@Override
public Swc4jAstVisitorResponse visitWithStmt(Swc4jAstWithStmt node) {
if (!options.isKeywordWithEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ public class BaseTestSuiteCheckers {
"const a = new XMLHttpRequest();", "XMLHttpRequest",
"const a = new WebAssembly();", "WebAssembly",
"const a = window;", "window",
"let Object = 1", "Object",
"Object.a = 1", "Object",
"let [ Object ] = [ 1 ]", "Object",
// SWC bug
// "{ Object } = { Object: 1 }", "Object",
"class Object {}", "Object",
"function Object() {}", "Object",
"class $abc {}", "$abc",
"function $abc() {}", "$abc");

Expand All @@ -78,11 +85,20 @@ protected JavetSanitizerException assertException(
JavetSanitizerException.class,
() -> checker.check(code),
"Failed to throw exception for [" + code + "]");
assertEquals(expectedError.getCode(), exception.getError().getCode());
assertEquals(
expectedError.getCode(),
exception.getError().getCode(),
"Error code mismatches for " + code);
if (detailed) {
assertEquals(expectedErrorMessage, exception.getDetailedMessage());
assertEquals(
expectedErrorMessage,
exception.getDetailedMessage(),
"Detailed error message mismatches for " + code);
} else {
assertEquals(expectedErrorMessage, exception.getMessage());
assertEquals(
expectedErrorMessage,
exception.getMessage(),
"Error message mismatches for " + code);
}
return exception;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ public void testModules() {
}
}

@Test
public void testReservedIdentifiers() {
JavetSanitizerOptions options = JavetSanitizerOptions.Default.toClone()
.setReservedIdentifierMatcher(name -> name.startsWith("$"));
options.getReservedIdentifierSet().add("$a");
checker.setOptions(options.seal());
assertException(
"const $a = 1; const $b = 1;",
JavetSanitizerError.IdentifierNotAllowed,
"Identifier $b is not allowed.\n" +
"Source: $b\n" +
"Line: 1\n" +
"Column: 21\n" +
"Start: 20\n" +
"End: 22");
}

@Test
public void testValidCases() throws JavetSanitizerException {
List<String> statements = SimpleList.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void testInvalidCases() {
identifiers.forEach(identifier -> {
assertFalse(
JavetSanitizerIdentifierMatcher.getInstance().matches(JavetSanitizerOptions.Default, identifier),
identifier + " should pass.");
identifier + " should not match.");
});
}

Expand All @@ -41,6 +41,6 @@ public void testValidCases() {
JavetSanitizerOptions.Default.getDisallowedIdentifierSet().forEach(identifier ->
assertTrue(
JavetSanitizerIdentifierMatcher.getInstance().matches(JavetSanitizerOptions.Default, identifier),
identifier + " should pass."));
identifier + " should match."));
}
}

0 comments on commit fd346fe

Please sign in to comment.