Skip to content

Commit

Permalink
🐞 fix: Fix asDouble() for ast array lit
Browse files Browse the repository at this point in the history
  • Loading branch information
caoccao committed May 17, 2024
1 parent c03f171 commit a68694e
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class Swc4jAstIdent
implements ISwc4jAstExpr, ISwc4jAstProp, ISwc4jAstTsModuleRef, ISwc4jAstModuleExportName, ISwc4jAstTsEntityName,
ISwc4jAstPropName, ISwc4jAstTsModuleName, ISwc4jAstJsxObject, ISwc4jAstJsxElementName, ISwc4jAstMemberProp,
ISwc4jAstSuperProp, ISwc4jAstJsxAttrName, ISwc4jAstTsThisTypeOrIdent, ISwc4jAstTsEnumMemberId {
public static final String UNDEFINED = "undefined";
protected static final String QUESTION_MARK = "?";
protected boolean optional;
@Jni2RustField(atom = true)
Expand All @@ -51,6 +52,10 @@ public Swc4jAstIdent(
setSym(sym);
}

public static Swc4jAstIdent createUndefined() {
return new Swc4jAstIdent(UNDEFINED, false, Swc4jSpan.DUMMY);
}

@Override
public List<ISwc4jAst> getChildNodes() {
return EMPTY_CHILD_NODES;
Expand All @@ -71,6 +76,10 @@ public boolean isOptional() {
return optional;
}

public boolean isUndefined() {
return !optional && UNDEFINED.equals(sym);
}

@Override
public boolean replaceNode(ISwc4jAst oldNode, ISwc4jAst newNode) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,19 @@ public byte asByte() {

@Override
public double asDouble() {
if (!elems.isEmpty()) {
if (elems.size() == 1) {
switch (elems.size()) {
case 0:
return 0;
case 1:
return elems.get(0)
.map(Swc4jAstExprOrSpread::getExpr)
.filter(n -> n.getType() == Swc4jAstType.Number)
.map(n -> (Swc4jAstNumber) n)
.map(Swc4jAstNumber::getValue)
.orElse(Double.NaN);
}
default:
return Double.NaN;
}
return 0;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import com.caoccao.javet.swc4j.ast.clazz.Swc4jAstComputedPropName;
import com.caoccao.javet.swc4j.ast.enums.Swc4jAstType;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstBinExpr;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstIdent;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstMemberExpr;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstUnaryExpr;
import com.caoccao.javet.swc4j.ast.expr.lit.Swc4jAstArrayLit;
import com.caoccao.javet.swc4j.ast.expr.lit.Swc4jAstBool;
import com.caoccao.javet.swc4j.ast.expr.lit.Swc4jAstNumber;
import com.caoccao.javet.swc4j.ast.expr.lit.Swc4jAstStr;
Expand All @@ -31,6 +33,12 @@
import com.caoccao.javet.swc4j.ast.visitors.Swc4jAstVisitor;
import com.caoccao.javet.swc4j.ast.visitors.Swc4jAstVisitorResponse;

/**
* The type Swc4j plugin visitor jsfuck decoder.
* It partially implements the features.
*
* @since 0.8.0
*/
public class Swc4jPluginVisitorJsFuckDecoder extends Swc4jAstVisitor {
protected int count;

Expand Down Expand Up @@ -75,6 +83,10 @@ public Swc4jAstVisitorResponse visitBinExpr(Swc4jAstBinExpr node) {
String value = left.as(ISwc4jAstCoercionPrimitive.class).asString()
+ right.as(ISwc4jAstCoercionPrimitive.class).asString();
newNode = Swc4jAstStr.create(value);
} else if ((leftType == Swc4jAstType.ArrayLit && rightType == Swc4jAstType.Ident) ||
(leftType == Swc4jAstType.Ident && rightType == Swc4jAstType.ArrayLit)) {
String value = left.toString() + right;
newNode = Swc4jAstStr.create(value);
}
break;
default:
Expand All @@ -89,22 +101,39 @@ public Swc4jAstVisitorResponse visitBinExpr(Swc4jAstBinExpr node) {

@Override
public Swc4jAstVisitorResponse visitMemberExpr(Swc4jAstMemberExpr node) {
ISwc4jAst newNode = null;
ISwc4jAstExpr obj = node.getObj().unParenExpr();
ISwc4jAstMemberProp prop = node.getProp();
if (obj.getType() == Swc4jAstType.Str) {
if (prop.getType() == Swc4jAstType.ComputedPropName) {
Swc4jAstComputedPropName computedPropName = prop.as(Swc4jAstComputedPropName.class);
ISwc4jAstExpr expr = computedPropName.getExpr();
if (expr.getType() == Swc4jAstType.Number) {
switch (obj.getType()) {
case ArrayLit:
Swc4jAstArrayLit arrayLit = obj.as(Swc4jAstArrayLit.class);
if (arrayLit.getElems().isEmpty()) {
newNode = Swc4jAstIdent.createUndefined();
}
break;
case Str:
if (prop.getType() == Swc4jAstType.ComputedPropName) {
Swc4jAstComputedPropName computedPropName = prop.as(Swc4jAstComputedPropName.class);
ISwc4jAstExpr expr = computedPropName.getExpr().unParenExpr();
String value = obj.as(Swc4jAstStr.class).getValue();
int index = expr.as(Swc4jAstNumber.class).asInt();
if (index >= 0 && index < value.length()) {
value = value.substring(index, index + 1);
++count;
node.getParent().replaceNode(node, Swc4jAstStr.create(value));
switch (expr.getType()) {
case Number:
case Str:
int index = expr.as(ISwc4jAstCoercionPrimitive.class).asInt();
if (index >= 0 && index < value.length()) {
value = value.substring(index, index + 1);
newNode = Swc4jAstStr.create(value);
}
break;
}
}
}
break;
default:
break;
}
if (newNode != null) {
++count;
node.getParent().replaceNode(node, newNode);
}
return super.visitMemberExpr(node);
}
Expand All @@ -129,15 +158,18 @@ public Swc4jAstVisitorResponse visitUnaryExpr(Swc4jAstUnaryExpr node) {
break;
case Plus:
switch (arg.getType()) {
case ArrayLit:
case ArrayLit: {
newNode = Swc4jAstNumber.create(arg.as(Swc4jAstArrayLit.class).asDouble());
break;
}
case Bool:
newNode = Swc4jAstNumber.create(arg.as(ISwc4jAstCoercionPrimitive.class).asInt());
break;
case Number: {
Swc4jAstNumber number = arg.as(Swc4jAstNumber.class);
newNode = Swc4jAstNumber.create(number.getValue(), number.getRaw().orElse(null));
break;
}
break;
case Str: {
double value;
try {
Expand All @@ -146,8 +178,8 @@ public Swc4jAstVisitorResponse visitUnaryExpr(Swc4jAstUnaryExpr node) {
value = Double.NaN;
}
newNode = Swc4jAstNumber.create(value);
break;
}
break;
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ public void test() throws Swc4jCoreException {
testCaseMap.put("+(\"1e309\")", "Infinity;");
testCaseMap.put("020", "16;");
testCaseMap.put("0x20", "32;");
testCaseMap.put("+[![]]", "NaN;");
testCaseMap.put("[][[]]+[]", "\"undefined\";");
testCaseMap.put("([![]]+[][[]])[+!+[]+[+[]]]", "\"i\";");
testCaseMap.put("[+!+[]]+(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[!+[]+!+[]]+[+!+[]]", "\"1+1\";");
testCaseMap.put("(+((+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]+[+[]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+!+[]]])+[])[!+[]+!+[]]", "\"-\";");
testCaseMap.put("[+!+[]]+(+((+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]+[+[]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+!+[]]])+[])[!+[]+!+[]]+[+!+[]]", "\"1-1\";");
Expand Down

0 comments on commit a68694e

Please sign in to comment.