Huge String improvements

This commit is contained in:
SuspiciousActivity authored and GitHub committed 2020-11-25 23:14:14 +01:00
1 parent afc59d63d3
commit add82951e6
12 files changed
+366 -202

No files matched your search

+4 -4
View File
@@ -137,7 +137,7 @@ public class GlobalSearchBox extends JFrame {
openBox.model.clear(); openBox.model.clear();
Set<Info> set = new HashSet<>(); Set<Info> set = new HashSet<>();
if (!txtString.getText().isEmpty()) { if (!txtString.getText().isEmpty()) {
String str = UnicodeUtils.unescape(txtString.getText()); String str = UnicodeUtils.unescape(null, txtString.getText(), true);
if (ignoreCase) { if (ignoreCase) {
str = str.toLowerCase(); str = str.toLowerCase();
} }
@@ -157,11 +157,11 @@ public class GlobalSearchBox extends JFrame {
} }
} }
} else { } else {
String owner = UnicodeUtils.unescape(txtOwner.getText()); String owner = UnicodeUtils.unescape(null, txtOwner.getText(), true);
boolean wildCardOwner = owner.isEmpty(); boolean wildCardOwner = owner.isEmpty();
String name = UnicodeUtils.unescape(txtName.getText()); String name = UnicodeUtils.unescape(null, txtName.getText(), true);
boolean wildCardName = name.isEmpty(); boolean wildCardName = name.isEmpty();
String desc = UnicodeUtils.unescape(txtDesc.getText()); String desc = UnicodeUtils.unescape(null, txtDesc.getText(), true);
boolean wildCardDesc = desc.isEmpty(); boolean wildCardDesc = desc.isEmpty();
for (ClassNode cn : Main.classNodes.values()) { for (ClassNode cn : Main.classNodes.values()) {
for (MethodNode mn : cn.methods) { for (MethodNode mn : cn.methods) {
+2 -2
View File
@@ -84,8 +84,8 @@ public class RenameBox extends JFrame {
JOptionPane.showMessageDialog(null, "ClassNode not found!", "Error!", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(null, "ClassNode not found!", "Error!", JOptionPane.ERROR_MESSAGE);
return; return;
} }
String newName = UnicodeUtils.unescape(txtName.getText()); String newName = UnicodeUtils.unescape(null, txtName.getText(), true);
String newDesc = UnicodeUtils.unescape(txtDesc.getText()); String newDesc = UnicodeUtils.unescape(null, txtDesc.getText(), true);
if (ClassUtil.isObjectClassMethod(newName, newDesc, true)) { if (ClassUtil.isObjectClassMethod(newName, newDesc, true)) {
JOptionPane.showMessageDialog(null, "Invalid name!", "Error!", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(null, "Invalid name!", "Error!", JOptionPane.ERROR_MESSAGE);
return; return;
+1 -1
View File
@@ -76,7 +76,7 @@ public class TypeOpenBox extends JFrame {
if (txtSearch.getText().isEmpty()) { if (txtSearch.getText().isEmpty()) {
return; return;
} }
String search = UnicodeUtils.unescape(txtSearch.getText()).toLowerCase(); String search = UnicodeUtils.unescape(null, txtSearch.getText(), true).toLowerCase();
if (search.contains("/")) { if (search.contains("/")) {
for (String s : Main.classNodes.keySet()) { for (String s : Main.classNodes.keySet()) {
String className = s.substring(0, s.length() - 6); String className = s.substring(0, s.length() - 6);
+2 -2
View File
@@ -36,7 +36,7 @@ public class UnicodeBox extends JFrame {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
try { try {
textArea.setText(UnicodeUtils.escape(textArea.getText())); textArea.setText(UnicodeUtils.escape(null, textArea.getText(), true));
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
Main.showError(ex.getMessage()); Main.showError(ex.getMessage());
} }
@@ -50,7 +50,7 @@ public class UnicodeBox extends JFrame {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
try { try {
textArea.setText(UnicodeUtils.unescape(textArea.getText())); textArea.setText(UnicodeUtils.unescape(null, textArea.getText(), true));
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
Main.showError(ex.getMessage()); Main.showError(ex.getMessage());
} }
+104 -72
View File
@@ -1,5 +1,6 @@
package me.ByteEdit.edit; package me.ByteEdit.edit;
import java.io.BufferedReader;
import java.io.StringReader; import java.io.StringReader;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
@@ -9,6 +10,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.regex.Pattern;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
@@ -51,30 +53,47 @@ import me.ByteEdit.utils.UnicodeUtils;
public class Assembler { public class Assembler {
private static final Pattern SPACE = Pattern.compile(" ");
public static ClassNode assemble(String input) { public static ClassNode assemble(String input) {
Main.txtByteEditView.removeAllLineHighlights(); Main.txtByteEditView.removeAllLineHighlights();
CustomBufferedReader read = null; CustomBufferedReader read = null;
try { try {
ClassNode clazz = new ClassNode(); ClassNode clazz = new ClassNode();
HugeStringsRev hsr = new HugeStringsRev();
try (BufferedReader reader = new BufferedReader(new StringReader(input))) {
String s;
while (!(s = reader.readLine()).startsWith("// #SourceFile: ")) {
}
while (!(s = reader.readLine()).equals("// #Fields")) {
if (s.startsWith("#")) {
String[] split = SPACE.split(s, 2);
hsr.add(Integer.parseInt(split[0].substring(1, split[0].length() - 1)),
UnicodeUtils.unescape(null, split[1], true));
}
}
}
read = new CustomBufferedReader(new StringReader(input)); read = new CustomBufferedReader(new StringReader(input));
String s; String s;
while (!(s = read.readLine()).startsWith("// #Class v:")) { while (!(s = read.readLine()).startsWith("// #Class v:")) {
if (clazz.visibleAnnotations == null) { if (clazz.visibleAnnotations == null) {
clazz.visibleAnnotations = new ArrayList<>(); clazz.visibleAnnotations = new ArrayList<>();
} }
clazz.visibleAnnotations.add(parseAnnotation(s)); clazz.visibleAnnotations.add(parseAnnotation(hsr, s));
} }
clazz.version = Integer.parseInt(s.substring(12)); clazz.version = Integer.parseInt(s.substring(12));
while ((s = read.readLine()).startsWith("// ")) { while ((s = read.readLine()).startsWith("// ")) {
if (s.startsWith("// #Signature: ")) { if (s.startsWith("// #Signature: ")) {
clazz.signature = s.substring(15).equals("null") ? null : UnicodeUtils.unescape(s.substring(15)); clazz.signature = s.substring(15).equals("null") ? null
: UnicodeUtils.unescape(hsr, s.substring(15));
} else if (s.startsWith("// #OuterClass: ")) { } else if (s.startsWith("// #OuterClass: ")) {
clazz.outerClass = s.substring(16).equals("null") ? null : UnicodeUtils.unescape(s.substring(16)); clazz.outerClass = s.substring(16).equals("null") ? null
: UnicodeUtils.unescape(hsr, s.substring(16));
} else if (s.startsWith("// #OuterMethod: ")) { } else if (s.startsWith("// #OuterMethod: ")) {
String[] split = s.split(" "); String[] split = s.split(" ");
if (split.length > 3) { if (split.length > 3) {
clazz.outerMethod = UnicodeUtils.unescape(split[2]); clazz.outerMethod = UnicodeUtils.unescape(hsr, split[2]);
clazz.outerMethodDesc = UnicodeUtils.unescape(split[3]); clazz.outerMethodDesc = UnicodeUtils.unescape(hsr, split[3]);
} }
} else if (s.equals("// #InnerClasses:")) { } else if (s.equals("// #InnerClasses:")) {
clazz.innerClasses = new ArrayList<>(); clazz.innerClasses = new ArrayList<>();
@@ -137,9 +156,9 @@ public class Assembler {
access ^= ClassUtil.ACC_MANDATED; access ^= ClassUtil.ACC_MANDATED;
} }
} }
clazz.innerClasses.add(new InnerClassNode(UnicodeUtils.unescape(split[1]), clazz.innerClasses.add(new InnerClassNode(UnicodeUtils.unescape(hsr, split[1]),
split[2].equals("null") ? null : UnicodeUtils.unescape(split[2]), split[2].equals("null") ? null : UnicodeUtils.unescape(hsr, split[2]),
split[3].equals("null") ? null : UnicodeUtils.unescape(split[3]), access)); split[3].equals("null") ? null : UnicodeUtils.unescape(hsr, split[3]), access));
} }
} }
{ {
@@ -148,14 +167,14 @@ public class Assembler {
String interfaces = s.substring(s.lastIndexOf(" implements ") + 12); String interfaces = s.substring(s.lastIndexOf(" implements ") + 12);
clazz.interfaces = new ArrayList<>(); clazz.interfaces = new ArrayList<>();
for (String interf : interfaces.split(", ")) { for (String interf : interfaces.split(", ")) {
clazz.interfaces.add(UnicodeUtils.unescape(interf)); clazz.interfaces.add(UnicodeUtils.unescape(hsr, interf));
} }
s = s.substring(0, s.lastIndexOf(" implements ")); s = s.substring(0, s.lastIndexOf(" implements "));
} }
clazz.superName = UnicodeUtils.unescape(s.substring(s.lastIndexOf(" extends ") + 9)); clazz.superName = UnicodeUtils.unescape(hsr, s.substring(s.lastIndexOf(" extends ") + 9));
s = s.substring(0, s.lastIndexOf(" extends ")); s = s.substring(0, s.lastIndexOf(" extends "));
String[] split = s.split(" "); String[] split = s.split(" ");
clazz.name = UnicodeUtils.unescape(split[split.length - 1]); clazz.name = UnicodeUtils.unescape(hsr, split[split.length - 1]);
clazz.access = ClassUtil.ACC_SUPER; clazz.access = ClassUtil.ACC_SUPER;
switch (split[split.length - 2]) { switch (split[split.length - 2]) {
case "class": case "class":
@@ -192,7 +211,7 @@ public class Assembler {
} }
} }
s = read.readLine(); s = read.readLine();
clazz.sourceFile = s.substring(16).equals("null") ? null : UnicodeUtils.unescape(s.substring(16)); clazz.sourceFile = s.substring(16).equals("null") ? null : UnicodeUtils.unescape(hsr, s.substring(16));
while (!(s = read.readLine()).equals("// #Fields")) { while (!(s = read.readLine()).equals("// #Fields")) {
} }
clazz.fields = new ArrayList<>(); clazz.fields = new ArrayList<>();
@@ -207,7 +226,7 @@ public class Assembler {
annotationsForNext.add(s); annotationsForNext.add(s);
} else { } else {
if (s.startsWith("// #Signature: ")) { if (s.startsWith("// #Signature: ")) {
signature = UnicodeUtils.unescape(s.substring(15)); signature = UnicodeUtils.unescape(hsr, s.substring(15));
} else { } else {
String[] split = s.split(" "); String[] split = s.split(" ");
boolean hasValue = false; boolean hasValue = false;
@@ -218,9 +237,9 @@ public class Assembler {
if (hasValue) { if (hasValue) {
split = s.substring(0, s.indexOf(" = ")).split(" "); split = s.substring(0, s.indexOf(" = ")).split(" ");
} }
String name = UnicodeUtils.unescape(split[split.length - 1]); String name = UnicodeUtils.unescape(hsr, split[split.length - 1]);
String desc = UnicodeUtils.unescape(split[split.length - 2]); String desc = UnicodeUtils.unescape(hsr, split[split.length - 2]);
value = getValue((String) value, desc); value = getValue(hsr, (String) value, desc);
int access = 0; int access = 0;
if (split.length > 2) { if (split.length > 2) {
String cons = consolidateStrings(split, 0, split.length - 2); String cons = consolidateStrings(split, 0, split.length - 2);
@@ -283,7 +302,7 @@ public class Assembler {
node.visibleAnnotations = new ArrayList<>(); node.visibleAnnotations = new ArrayList<>();
} }
for (String anno : annotationsForNext) { for (String anno : annotationsForNext) {
node.visibleAnnotations.add(parseAnnotation(anno)); node.visibleAnnotations.add(parseAnnotation(hsr, anno));
} }
annotationsForNext.clear(); annotationsForNext.clear();
} }
@@ -319,7 +338,7 @@ public class Assembler {
tryCatchBlocksToParse.clear(); tryCatchBlocksToParse.clear();
stage = 0; stage = 0;
} else if (s.startsWith("// #Signature: ")) { } else if (s.startsWith("// #Signature: ")) {
node.signature = UnicodeUtils.unescape(s.substring(15)); node.signature = UnicodeUtils.unescape(hsr, s.substring(15));
} else if (s.equals("// #TryCatch:")) { } else if (s.equals("// #TryCatch:")) {
stage = 1; stage = 1;
} else if (s.equals("// #LocalVars:")) { } else if (s.equals("// #LocalVars:")) {
@@ -337,7 +356,7 @@ public class Assembler {
node.visibleAnnotations = new ArrayList<>(); node.visibleAnnotations = new ArrayList<>();
} }
for (String anno : annotationsForNext) { for (String anno : annotationsForNext) {
node.visibleAnnotations.add(parseAnnotation(anno)); node.visibleAnnotations.add(parseAnnotation(hsr, anno));
} }
annotationsForNext.clear(); annotationsForNext.clear();
} }
@@ -345,7 +364,7 @@ public class Assembler {
String[] sp = st.split(":"); String[] sp = st.split(":");
int start = Integer.parseInt(sp[3].substring(0, sp[3].length() - 2)); int start = Integer.parseInt(sp[3].substring(0, sp[3].length() - 2));
int end = Integer.parseInt(sp[4].substring(0, sp[4].length() - 4)); int end = Integer.parseInt(sp[4].substring(0, sp[4].length() - 4));
String signat = sp[5].equals("null") ? null : UnicodeUtils.unescape(sp[5]); String signat = sp[5].equals("null") ? null : UnicodeUtils.unescape(hsr, sp[5]);
LabelNode _start = null; LabelNode _start = null;
LabelNode _end = null; LabelNode _end = null;
for (Entry<LabelNode, Integer> entry : methodLabelMap.entrySet()) { for (Entry<LabelNode, Integer> entry : methodLabelMap.entrySet()) {
@@ -356,9 +375,9 @@ public class Assembler {
_end = entry.getKey(); _end = entry.getKey();
} }
} }
node.localVariables.add(new LocalVariableNode(UnicodeUtils.unescape(sp[0]), node.localVariables.add(new LocalVariableNode(UnicodeUtils.unescape(hsr, sp[0]),
UnicodeUtils.unescape(sp[1].substring(1, sp[1].length() - 2)), signat, _start, _end, UnicodeUtils.unescape(hsr, sp[1].substring(1, sp[1].length() - 2)), signat, _start,
Integer.parseInt(sp[2].substring(0, sp[2].length() - 2)))); _end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
} }
for (String st : tryCatchBlocksToParse) { for (String st : tryCatchBlocksToParse) {
String[] sp = st.split(" "); String[] sp = st.split(" ");
@@ -380,7 +399,7 @@ public class Assembler {
} }
} }
node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler, node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler,
sp[0].equals("null") ? null : UnicodeUtils.unescape(sp[0]))); sp[0].equals("null") ? null : UnicodeUtils.unescape(hsr, sp[0])));
} }
clazz.methods.add(node); clazz.methods.add(node);
} else if (!s.startsWith("\t")) { } else if (!s.startsWith("\t")) {
@@ -388,13 +407,13 @@ public class Assembler {
if (s.contains(" throws ")) { if (s.contains(" throws ")) {
String exceptions = s.substring(s.lastIndexOf(" throws ") + 8); String exceptions = s.substring(s.lastIndexOf(" throws ") + 8);
for (String excp : exceptions.split(", ")) { for (String excp : exceptions.split(", ")) {
node.exceptions.add(UnicodeUtils.unescape(excp)); node.exceptions.add(UnicodeUtils.unescape(hsr, excp));
} }
s = s.substring(0, s.lastIndexOf(" throws ")); s = s.substring(0, s.lastIndexOf(" throws "));
} }
String[] split = s.split(" "); String[] split = s.split(" ");
node.desc = UnicodeUtils.unescape(split[split.length - 1]); node.desc = UnicodeUtils.unescape(hsr, split[split.length - 1]);
node.name = UnicodeUtils.unescape(split[split.length - 2]); node.name = UnicodeUtils.unescape(hsr, split[split.length - 2]);
int access = 0; int access = 0;
if (split.length > 2) { if (split.length > 2) {
String cons = consolidateStrings(split, 0, split.length - 2); String cons = consolidateStrings(split, 0, split.length - 2);
@@ -458,7 +477,7 @@ public class Assembler {
if (!temp.isEmpty()) { if (!temp.isEmpty()) {
if (s.equals("]")) { if (s.equals("]")) {
temp += s; temp += s;
node.instructions.add(getNode(temp, methodLabelMap)); node.instructions.add(getNode(hsr, temp, methodLabelMap));
temp = ""; temp = "";
} else { } else {
temp += s + "\n"; temp += s + "\n";
@@ -467,7 +486,7 @@ public class Assembler {
if (s.endsWith("[")) { if (s.endsWith("[")) {
temp += s + "\n"; temp += s + "\n";
} else { } else {
node.instructions.add(getNode(s, methodLabelMap)); node.instructions.add(getNode(hsr, s, methodLabelMap));
} }
} }
} }
@@ -496,31 +515,37 @@ public class Assembler {
ArrayList<String> ret = new ArrayList<>(); ArrayList<String> ret = new ArrayList<>();
String[] split = s.split(", "); String[] split = s.split(", ");
String building = null; String building = null;
boolean inString = false;
for (int i = 0; i < split.length; i++) { for (int i = 0; i < split.length; i++) {
if (split[i].startsWith("(")) { if (split[i].startsWith("(")) {
ret.add(split[i]); ret.add(split[i]);
} else if (split[i].endsWith("\"")) { } else if (split[i].startsWith("\"") && split[i].endsWith("\"")) {
ret.add(split[i]);
} else if (split[i].endsWith("\"") && inString) {
if (building == null) if (building == null)
ret.add(split[i]); ret.add(split[i]);
else else
ret.add(building + ", " + split[i]); ret.add(building + ", " + split[i]);
building = null; building = null;
} else { } else if (inString || split[i].startsWith("\"")) {
inString = true;
if (building == null) if (building == null)
building = split[i]; building = split[i];
else else
building += ", " + split[i]; building += ", " + split[i];
} else {
ret.add(split[i]);
} }
} }
return ret.toArray(new String[0]); return ret.toArray(new String[0]);
} }
private static AnnotationNode parseAnnotation(String s) { private static AnnotationNode parseAnnotation(HugeStringsRev hsr, String s) {
s = s.substring(1); s = s.substring(1);
String[] split = s.split(" "); String[] split = s.split(" ");
AnnotationNode node = new AnnotationNode(UnicodeUtils.unescape(split[0])); AnnotationNode node = new AnnotationNode(UnicodeUtils.unescape(hsr, split[0]));
if (split.length > 1) { if (split.length > 1) {
if (node.values == null) { if (node.values == null) {
node.values = new ArrayList<>(); node.values = new ArrayList<>();
@@ -538,7 +563,7 @@ public class Assembler {
String split3[] = splitWithStrings(value.substring(2, value.length() - 2)); String split3[] = splitWithStrings(value.substring(2, value.length() - 2));
List<Object> list = new ArrayList<>(); List<Object> list = new ArrayList<>();
for (String rofl : split3) { for (String rofl : split3) {
rofl = UnicodeUtils.unescape(rofl); rofl = UnicodeUtils.unescape(hsr, rofl);
if (rofl.startsWith("\"")) { if (rofl.startsWith("\"")) {
int index = rofl.lastIndexOf("\""); int index = rofl.lastIndexOf("\"");
list.add(rofl.substring(1, index)); list.add(rofl.substring(1, index));
@@ -552,7 +577,7 @@ public class Assembler {
} }
node.values.add(list); node.values.add(list);
} else { } else {
value = UnicodeUtils.unescape(value); value = UnicodeUtils.unescape(hsr, value);
if (value.startsWith("\"")) { if (value.startsWith("\"")) {
int index = value.lastIndexOf("\""); int index = value.lastIndexOf("\"");
node.values.add(value.substring(1, index)); node.values.add(value.substring(1, index));
@@ -596,7 +621,7 @@ public class Assembler {
return ret; return ret;
} }
private static Object getValue(String s, String to) { private static Object getValue(HugeStringsRev hsr, String s, String to) {
if (s == null) { if (s == null) {
return null; return null;
} }
@@ -618,14 +643,15 @@ public class Assembler {
case "S": case "S":
return Short.parseShort(s); return Short.parseShort(s);
case "Ljava/lang/String;": case "Ljava/lang/String;":
return UnicodeUtils.unescape(s.substring(1, s.length() - 1)); return UnicodeUtils.unescape(hsr, s.substring(1, s.length() - 1));
default: { default: {
return null; return null;
} }
} }
} }
private static AbstractInsnNode getNode(String s, HashMap<LabelNode, Integer> labels) throws Exception { private static AbstractInsnNode getNode(HugeStringsRev hsr, String s, HashMap<LabelNode, Integer> labels)
throws Exception {
if (s.startsWith("// label ")) { if (s.startsWith("// label ")) {
int labelNr = Integer.parseInt(s.substring(9)); int labelNr = Integer.parseInt(s.substring(9));
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) { for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
@@ -666,7 +692,7 @@ public class Assembler {
if (frameType != -1) if (frameType != -1)
arr.add(new Integer(frameType)); arr.add(new Integer(frameType));
else { else {
String frame = UnicodeUtils.unescape(asd); String frame = UnicodeUtils.unescape(hsr, asd);
frame = frame.substring(1, frame.length() - 1); frame = frame.substring(1, frame.length() - 1);
arr.add(frame); arr.add(frame);
} }
@@ -712,7 +738,7 @@ public class Assembler {
if (frameType != -1) if (frameType != -1)
arr.add(new Integer(frameType)); arr.add(new Integer(frameType));
else { else {
String frame = UnicodeUtils.unescape(asd); String frame = UnicodeUtils.unescape(hsr, asd);
frame = frame.substring(1, frame.length() - 1); frame = frame.substring(1, frame.length() - 1);
arr.add(frame); arr.add(frame);
} }
@@ -818,10 +844,10 @@ public class Assembler {
String type = split2[0].substring(7); String type = split2[0].substring(7);
// Reflection // Reflection
val = new Type(ClassUtil.getIDFromClassNameForType(type), val = new Type(ClassUtil.getIDFromClassNameForType(type),
UnicodeUtils.unescape(split2[3].substring(6, split2[3].length() - 1)), UnicodeUtils.unescape(hsr, split2[3].substring(6, split2[3].length() - 1)),
Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5))); Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5)));
} else if (str.startsWith("\"") && str.endsWith("\"")) { } else if (str.startsWith("\"") && str.endsWith("\"")) {
val = UnicodeUtils.unescape(str.substring(1, str.length() - 1)); val = UnicodeUtils.unescape(hsr, str.substring(1, str.length() - 1));
} else if (str.endsWith("l")) { } else if (str.endsWith("l")) {
val = Long.parseLong(str.substring(0, str.length() - 1)); val = Long.parseLong(str.substring(0, str.length() - 1));
} else if (str.endsWith("f")) { } else if (str.endsWith("f")) {
@@ -1437,50 +1463,54 @@ public class Assembler {
case "getstatic": { case "getstatic": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new FieldInsnNode(178, UnicodeUtils.unescape(target.substring(0, index)), return new FieldInsnNode(178, UnicodeUtils.unescape(hsr, target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]));
} }
case "putstatic": { case "putstatic": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new FieldInsnNode(179, UnicodeUtils.unescape(target.substring(0, index)), return new FieldInsnNode(179, UnicodeUtils.unescape(hsr, target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]));
} }
case "getfield": { case "getfield": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new FieldInsnNode(180, UnicodeUtils.unescape(target.substring(0, index)), return new FieldInsnNode(180, UnicodeUtils.unescape(hsr, target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]));
} }
case "putfield": { case "putfield": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new FieldInsnNode(181, UnicodeUtils.unescape(target.substring(0, index)), return new FieldInsnNode(181, UnicodeUtils.unescape(hsr, target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]));
} }
case "invokevirtual": { case "invokevirtual": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new MethodInsnNode(182, UnicodeUtils.unescape(target.substring(0, index)), return new MethodInsnNode(182, UnicodeUtils.unescape(hsr, target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false); UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]),
false);
} }
case "invokespecial": { case "invokespecial": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new MethodInsnNode(183, UnicodeUtils.unescape(target.substring(0, index)), return new MethodInsnNode(183, UnicodeUtils.unescape(hsr, target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false); UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]),
false);
} }
case "invokestatic": { case "invokestatic": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new MethodInsnNode(184, UnicodeUtils.unescape(target.substring(0, index)), return new MethodInsnNode(184, UnicodeUtils.unescape(hsr, target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false); UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]),
false);
} }
case "invokeinterface": { case "invokeinterface": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new MethodInsnNode(185, UnicodeUtils.unescape(target.substring(0, index)), return new MethodInsnNode(185, UnicodeUtils.unescape(hsr, target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), true); UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]),
true);
} }
case "invokedynamic": { case "invokedynamic": {
String str = s.substring(16, s.length() - 2).replace("", ""); String str = s.substring(16, s.length() - 2).replace("", "");
@@ -1495,7 +1525,7 @@ public class Assembler {
try { try {
// Reflection // Reflection
args.add(new Type(ClassUtil.getIDFromClassNameForType(vals.get(0).substring(6)), args.add(new Type(ClassUtil.getIDFromClassNameForType(vals.get(0).substring(6)),
UnicodeUtils.unescape(vals.get(3).substring(6, vals.get(3).length() - 1)), UnicodeUtils.unescape(hsr, vals.get(3).substring(6, vals.get(3).length() - 1)),
Integer.parseInt(vals.get(1).substring(7)), Integer.parseInt(vals.get(1).substring(7)),
Integer.parseInt(vals.get(2).substring(5)))); Integer.parseInt(vals.get(2).substring(5))));
} catch (Exception e) { } catch (Exception e) {
@@ -1503,9 +1533,9 @@ public class Assembler {
} }
} else if (stage == 2) { } else if (stage == 2) {
args.add(new Handle(OpcodesReverse.getHandleOpcode(vals.get(4).substring(5)), args.add(new Handle(OpcodesReverse.getHandleOpcode(vals.get(4).substring(5)),
UnicodeUtils.unescape(vals.get(1).substring(7)), UnicodeUtils.unescape(hsr, vals.get(1).substring(7)),
UnicodeUtils.unescape(vals.get(0).substring(6)), UnicodeUtils.unescape(hsr, vals.get(0).substring(6)),
UnicodeUtils.unescape(vals.get(2).substring(6)), UnicodeUtils.unescape(hsr, vals.get(2).substring(6)),
Boolean.parseBoolean(vals.get(3).substring(13)))); Boolean.parseBoolean(vals.get(3).substring(13))));
vals.clear(); vals.clear();
} }
@@ -1523,7 +1553,7 @@ public class Assembler {
vals.add(st); vals.add(st);
} else if (stage == 0) { } else if (stage == 0) {
if (st.startsWith("\"") && st.endsWith("\"")) { if (st.startsWith("\"") && st.endsWith("\"")) {
args.add(UnicodeUtils.unescape(st.substring(1, st.length() - 1))); args.add(UnicodeUtils.unescape(hsr, st.substring(1, st.length() - 1)));
} else if (st.endsWith("l")) { } else if (st.endsWith("l")) {
args.add(Long.parseLong(st.substring(0, st.length() - 1))); args.add(Long.parseLong(st.substring(0, st.length() - 1)));
} else if (st.endsWith("f")) { } else if (st.endsWith("f")) {
@@ -1541,21 +1571,23 @@ public class Assembler {
_args[stage] = o; _args[stage] = o;
stage++; stage++;
} }
return new InvokeDynamicInsnNode(UnicodeUtils.unescape(sp[0].substring(7)), return new InvokeDynamicInsnNode(UnicodeUtils.unescape(hsr, sp[0].substring(7)),
UnicodeUtils.unescape(sp[1].substring(6)), UnicodeUtils.unescape(hsr, sp[1].substring(6)),
new Handle(OpcodesReverse.getHandleOpcode(sp[7].substring(6)), new Handle(OpcodesReverse.getHandleOpcode(sp[7].substring(6)),
UnicodeUtils.unescape(sp[4].substring(8)), UnicodeUtils.unescape(sp[3].substring(7)), UnicodeUtils.unescape(hsr, sp[4].substring(8)),
UnicodeUtils.unescape(sp[5].substring(7)), Boolean.parseBoolean(sp[6].substring(14))), UnicodeUtils.unescape(hsr, sp[3].substring(7)),
UnicodeUtils.unescape(hsr, sp[5].substring(7)),
Boolean.parseBoolean(sp[6].substring(14))),
_args); _args);
} }
case "new": { case "new": {
return new TypeInsnNode(187, UnicodeUtils.unescape(split[1])); return new TypeInsnNode(187, UnicodeUtils.unescape(hsr, split[1]));
} }
case "newarray": { case "newarray": {
return new IntInsnNode(188, ClassUtil.getArrayIDByType(split[1])); return new IntInsnNode(188, ClassUtil.getArrayIDByType(split[1]));
} }
case "anewarray": { case "anewarray": {
return new TypeInsnNode(189, UnicodeUtils.unescape(split[1])); return new TypeInsnNode(189, UnicodeUtils.unescape(hsr, split[1]));
} }
case "arraylength": { case "arraylength": {
return new InsnNode(190); return new InsnNode(190);
@@ -1564,10 +1596,10 @@ public class Assembler {
return new InsnNode(191); return new InsnNode(191);
} }
case "checkcast": { case "checkcast": {
return new TypeInsnNode(192, UnicodeUtils.unescape(split[1])); return new TypeInsnNode(192, UnicodeUtils.unescape(hsr, split[1]));
} }
case "instanceof": { case "instanceof": {
return new TypeInsnNode(193, UnicodeUtils.unescape(split[1])); return new TypeInsnNode(193, UnicodeUtils.unescape(hsr, split[1]));
} }
case "monitorenter": { case "monitorenter": {
return new InsnNode(194); return new InsnNode(194);
@@ -1576,7 +1608,7 @@ public class Assembler {
return new InsnNode(195); return new InsnNode(195);
} }
case "multianewarray": { case "multianewarray": {
return new MultiANewArrayInsnNode(UnicodeUtils.unescape(split[1]), Integer.parseInt(split[2])); return new MultiANewArrayInsnNode(UnicodeUtils.unescape(hsr, split[1]), Integer.parseInt(split[2]));
} }
case "ifnull": { case "ifnull": {
int labelNr = Integer.parseInt(s.split(" ")[1]); int labelNr = Integer.parseInt(s.split(" ")[1]);
+106 -95
View File
@@ -83,53 +83,60 @@ public class Disassembler {
return new DisassembleTuple("ClassNode is null! This is not a valid java class file!"); return new DisassembleTuple("ClassNode is null! This is not a valid java class file!");
} }
try { try {
HugeStrings hs = new HugeStrings();
AtomicInteger lineFound = new AtomicInteger(-1); AtomicInteger lineFound = new AtomicInteger(-1);
StringContext ctx = new StringContext(16); StringContext ctx = new StringContext(18);
ctx.next("// #Annotations:\n"); ctx.next("// #Annotations:\n");
ctx.next(doAnnotations(classNode.visibleAnnotations)); ctx.next(doAnnotations(classNode.visibleAnnotations, hs));
ctx.next("// #Class v:" + classNode.version + "\n"); ctx.next("// #Class v:" + classNode.version + "\n");
if (classNode.signature != null) if (classNode.signature != null)
ctx.next("// #Signature: " + UnicodeUtils.escapeWithSpaces(classNode.signature) + "\n"); ctx.next("// #Signature: " + UnicodeUtils.escapeWithSpaces(hs, classNode.signature) + "\n");
if (classNode.outerMethod != null) if (classNode.outerMethod != null)
ctx.next("// #OuterMethod: " + (classNode.outerMethod == null ? "null" ctx.next(
: (UnicodeUtils.escapeWithSpaces(classNode.outerMethod) + " " "// #OuterMethod: "
+ UnicodeUtils.escapeWithSpaces(classNode.outerMethodDesc))) + (classNode.outerMethod == null ? "null"
: (UnicodeUtils.escapeWithSpaces(hs, classNode.outerMethod) + " "
+ UnicodeUtils.escapeWithSpaces(hs, classNode.outerMethodDesc)))
+ "\n"); + "\n");
if (classNode.outerClass != null) if (classNode.outerClass != null)
ctx.next("// #OuterClass: " + UnicodeUtils.escapeWithSpaces(classNode.outerClass) + "\n"); ctx.next("// #OuterClass: " + UnicodeUtils.escapeWithSpaces(hs, classNode.outerClass) + "\n");
ctx.next("// #InnerClasses:\n"); ctx.next("// #InnerClasses:\n");
if (classNode.innerClasses != null) { if (classNode.innerClasses != null) {
String ics = ""; String ics = "";
for (InnerClassNode icn : classNode.innerClasses) { for (InnerClassNode icn : classNode.innerClasses) {
ics += "// " + UnicodeUtils.escapeWithSpaces(icn.name) + " " ics += "// " + UnicodeUtils.escapeWithSpaces(hs, icn.name) + " "
+ UnicodeUtils.escapeWithSpaces(icn.outerName) + " " + UnicodeUtils.escapeWithSpaces(hs, icn.outerName) + " "
+ UnicodeUtils.escapeWithSpaces(icn.innerName) + UnicodeUtils.escapeWithSpaces(hs, icn.innerName)
+ (icn.access == 0 ? "" : " " + ClassUtil.getAccessFlagsFull(icn.access).trim()) + "\n"; + (icn.access == 0 ? "" : " " + ClassUtil.getAccessFlagsFull(icn.access).trim()) + "\n";
} }
ctx.next(ics); ctx.next(ics);
} }
ctx.next(ClassUtil.getAccessFlagsClass(classNode.access) + UnicodeUtils.escapeWithSpaces(classNode.name) ctx.next(ClassUtil.getAccessFlagsClass(classNode.access) + UnicodeUtils.escapeWithSpaces(hs, classNode.name)
+ " "); + " ");
ctx.next("extends " + UnicodeUtils.escapeWithSpaces(classNode.superName) + " "); ctx.next("extends " + UnicodeUtils.escapeWithSpaces(hs, classNode.superName) + " ");
if (classNode.interfaces != null && !classNode.interfaces.isEmpty()) { if (classNode.interfaces != null && !classNode.interfaces.isEmpty()) {
String interfaceStr = ""; String interfaceStr = "";
for (String interfc : classNode.interfaces) { for (String interfc : classNode.interfaces) {
if (interfaceStr.isEmpty()) { if (interfaceStr.isEmpty()) {
interfaceStr += UnicodeUtils.escapeWithSpaces(interfc); interfaceStr += UnicodeUtils.escapeWithSpaces(hs, interfc);
} else { } else {
interfaceStr += ", " + UnicodeUtils.escapeWithSpaces(interfc); interfaceStr += ", " + UnicodeUtils.escapeWithSpaces(hs, interfc);
} }
} }
if (!interfaceStr.isEmpty()) if (!interfaceStr.isEmpty())
ctx.next("implements " + interfaceStr + " "); ctx.next("implements " + interfaceStr + " ");
} }
ctx.next("{\n// #SourceFile: " ctx.next("{\n// #SourceFile: "
+ (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(classNode.sourceFile)) + (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(hs, classNode.sourceFile)) + "\n");
+ "\n\n// #Fields\n"); int hugeIdx = ctx.next("");
ctx.next(doFields(classNode.fields, nodeToFind, lineFound)); ctx.next("\n// #Fields\n");
ctx.next(doFields(classNode.fields, nodeToFind, lineFound, hs));
ctx.next("\n// #Methods\n"); ctx.next("\n// #Methods\n");
ctx.next(doMethods(classNode.methods, classNode.name, nodeToFind, lineFound)); ctx.next(doMethods(classNode.methods, classNode.name, nodeToFind, lineFound, hs));
ctx.next("}\n"); ctx.next("}\n");
if (!hs.isEmpty())
ctx.set(hugeIdx, hs.makeStringsList());
return new DisassembleTuple(ctx.finish(), lineFound.get()); return new DisassembleTuple(ctx.finish(), lineFound.get());
} catch (Throwable e) { } catch (Throwable e) {
return new DisassembleTuple("Class couldn't be decompiled:\n" + e.getClass().getName() + ": " return new DisassembleTuple("Class couldn't be decompiled:\n" + e.getClass().getName() + ": "
@@ -139,12 +146,12 @@ public class Disassembler {
} }
} }
private static String doAnnotations(List<AnnotationNode> annotations) { private static String doAnnotations(List<AnnotationNode> annotations, HugeStrings hs) {
if (annotations == null) if (annotations == null)
return ""; return "";
StringContext ctx = new StringContext(annotations.size()); StringContext ctx = new StringContext(annotations.size());
for (AnnotationNode annotationNode : annotations) { for (AnnotationNode annotationNode : annotations) {
String s = "@" + UnicodeUtils.escapeWithSpaces(annotationNode.desc); String s = "@" + UnicodeUtils.escapeWithSpaces(hs, annotationNode.desc);
if (annotationNode.values != null && !annotationNode.values.isEmpty()) { if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
s += " ("; s += " (";
boolean valBefore = true; boolean valBefore = true;
@@ -159,10 +166,10 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += UnicodeUtils.escapeWithSpaces(rofl) + "/"; s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += UnicodeUtils.escapeWithSpaces(rofl) + "]"; s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "]";
} }
} }
s += ", "; s += ", ";
@@ -175,21 +182,21 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += UnicodeUtils.escapeWithSpaces(rofl) + "/"; s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += UnicodeUtils.escapeWithSpaces(rofl); s += UnicodeUtils.escapeWithSpaces(hs, rofl);
} }
} }
} else { } else {
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\""; s += "\"" + UnicodeUtils.escape(hs, String.valueOf(obj)) + "\"";
} }
s += ", "; s += ", ";
} }
s = s.substring(0, s.length() - 2); s = s.substring(0, s.length() - 2);
s += " }]"; s += " }]";
} else if (o instanceof String) { } else if (o instanceof String) {
s += "\"" + UnicodeUtils.escapeWithSpaces((String) o) + "\"], "; s += "\"" + UnicodeUtils.escapeWithSpaces(hs, (String) o) + "\"], ";
} else { } else {
s += "(" + o.getClass().getName().replace(".", "/") + ") " + o + "], "; s += "(" + o.getClass().getName().replace(".", "/") + ") " + o + "], ";
} }
@@ -207,7 +214,7 @@ public class Disassembler {
} }
private static String doMethods(List<MethodNode> methods, String className, Object nodeToFind, private static String doMethods(List<MethodNode> methods, String className, Object nodeToFind,
AtomicInteger lineFound) throws InterruptedException, ExecutionException { AtomicInteger lineFound, HugeStrings hs) throws InterruptedException, ExecutionException {
Future<String>[] futures = new Future[methods.size()]; Future<String>[] futures = new Future[methods.size()];
for (int i = 0; i < futures.length; i++) { for (int i = 0; i < futures.length; i++) {
MethodNode mn = methods.get(i); MethodNode mn = methods.get(i);
@@ -218,8 +225,8 @@ public class Disassembler {
try { try {
ms += "\t// #Max: l:" + mn.maxLocals + " s:" + mn.maxStack + "\n"; ms += "\t// #Max: l:" + mn.maxLocals + " s:" + mn.maxStack + "\n";
if (mn.signature != null) if (mn.signature != null)
ms += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(mn.signature) + "\n"; ms += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(hs, mn.signature) + "\n";
String[] dis = disassembleMethod(className, mn); String[] dis = disassembleMethod(className, mn, hs);
ms += dis[2]; ms += dis[2];
ms += dis[1]; ms += dis[1];
if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty()) { if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty()) {
@@ -239,10 +246,10 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
ms += UnicodeUtils.escapeWithSpaces(rofl) + "/"; ms += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
ms += UnicodeUtils.escapeWithSpaces(rofl) + "]"; ms += UnicodeUtils.escapeWithSpaces(hs, rofl) + "]";
} }
} }
ms += ", "; ms += ", ";
@@ -255,14 +262,15 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
ms += UnicodeUtils.escapeWithSpaces(rofl) + "/"; ms += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
ms += UnicodeUtils.escapeWithSpaces(rofl); ms += UnicodeUtils.escapeWithSpaces(hs, rofl);
} }
} }
} else { } else {
ms += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\""; ms += "\"" + UnicodeUtils.escape(hs, String.valueOf(obj))
+ "\"";
} }
ms += ", "; ms += ", ";
} }
@@ -284,15 +292,16 @@ public class Disassembler {
if (mn.equals(nodeToFind)) { if (mn.equals(nodeToFind)) {
lineFound.set(ms.split("\\n").length); lineFound.set(ms.split("\\n").length);
} }
ms += "\t" + ClassUtil.getAccessFlagsFull(mn.access) + UnicodeUtils.escapeWithSpaces(mn.name) ms += "\t" + ClassUtil.getAccessFlagsFull(mn.access)
+ " " + UnicodeUtils.escapeWithSpaces(mn.desc) + " "; + UnicodeUtils.escapeWithSpaces(hs, mn.name) + " "
+ UnicodeUtils.escapeWithSpaces(hs, mn.desc) + " ";
if (mn.exceptions != null && !mn.exceptions.isEmpty()) { if (mn.exceptions != null && !mn.exceptions.isEmpty()) {
String exceptionStr = ""; String exceptionStr = "";
for (String exc : mn.exceptions) { for (String exc : mn.exceptions) {
if (exceptionStr.isEmpty()) { if (exceptionStr.isEmpty()) {
exceptionStr += UnicodeUtils.escapeWithSpaces(exc); exceptionStr += UnicodeUtils.escapeWithSpaces(hs, exc);
} else { } else {
exceptionStr += ", " + UnicodeUtils.escapeWithSpaces(exc); exceptionStr += ", " + UnicodeUtils.escapeWithSpaces(hs, exc);
} }
} }
if (!exceptionStr.isEmpty()) if (!exceptionStr.isEmpty())
@@ -321,15 +330,15 @@ public class Disassembler {
return s; return s;
} }
private static String doFields(List<FieldNode> fields, Object nodeToFind, AtomicInteger lineFound) { private static String doFields(List<FieldNode> fields, Object nodeToFind, AtomicInteger lineFound, HugeStrings hs) {
StringContext ctx = new StringContext(fields.size()); StringContext ctx = new StringContext(fields.size());
for (FieldNode fn : fields) { for (FieldNode fn : fields) {
String s = ""; String s = "";
if (fn.signature != null) if (fn.signature != null)
s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(fn.signature) + "\n"; s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(hs, fn.signature) + "\n";
if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty()) { if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty()) {
for (AnnotationNode annotationNode : fn.visibleAnnotations) { for (AnnotationNode annotationNode : fn.visibleAnnotations) {
s += "\t@" + UnicodeUtils.escapeWithSpaces(annotationNode.desc); s += "\t@" + UnicodeUtils.escapeWithSpaces(hs, annotationNode.desc);
if (annotationNode.values != null && !annotationNode.values.isEmpty()) { if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
s += " ("; s += " (";
boolean valBefore = true; boolean valBefore = true;
@@ -344,10 +353,10 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += UnicodeUtils.escapeWithSpaces(rofl) + "/"; s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += UnicodeUtils.escapeWithSpaces(rofl) + "]"; s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "]";
} }
} }
s += ", "; s += ", ";
@@ -360,14 +369,14 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += UnicodeUtils.escapeWithSpaces(rofl) + "/"; s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += UnicodeUtils.escapeWithSpaces(rofl); s += UnicodeUtils.escapeWithSpaces(hs, rofl);
} }
} }
} else { } else {
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\""; s += "\"" + UnicodeUtils.escape(hs, String.valueOf(obj)) + "\"";
} }
s += ", "; s += ", ";
} }
@@ -390,9 +399,9 @@ public class Disassembler {
lineFound.set(s.split("\\n").length); lineFound.set(s.split("\\n").length);
} }
s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient")
+ UnicodeUtils.escapeWithSpaces(fn.desc) + " " + UnicodeUtils.escapeWithSpaces(fn.name); + UnicodeUtils.escapeWithSpaces(hs, fn.desc) + " " + UnicodeUtils.escapeWithSpaces(hs, fn.name);
if (fn.value != null) { if (fn.value != null) {
s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc, true); s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc, true, hs);
} }
s += "\n"; s += "\n";
ctx.next(s); ctx.next(s);
@@ -400,7 +409,7 @@ public class Disassembler {
return ctx.finish(); return ctx.finish();
} }
private static String[] disassembleMethod(String className, MethodNode mn) { private static String[] disassembleMethod(String className, MethodNode mn, HugeStrings hs) {
HashMap<Label, Integer> labels = new HashMap<Label, Integer>(); HashMap<Label, Integer> labels = new HashMap<Label, Integer>();
String localVarTable; String localVarTable;
String tryCatchTable; String tryCatchTable;
@@ -414,10 +423,10 @@ public class Disassembler {
StringContext ctx = new StringContext(list.size() + 1); StringContext ctx = new StringContext(list.size() + 1);
ctx.next("\t// #LocalVars:\n"); ctx.next("\t// #LocalVars:\n");
for (LocalVariableNode lvn : list) { for (LocalVariableNode lvn : list) {
ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(lvn.name) + ": " ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(hs, lvn.name) + ": "
+ UnicodeUtils.escapeWithSpaces(lvn.desc) + " i:" + lvn.index + " s:" + UnicodeUtils.escapeWithSpaces(hs, lvn.desc) + " i:" + lvn.index + " s:"
+ labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + " sig:" + labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + " sig:"
+ UnicodeUtils.escapeWithSpaces(lvn.signature) + "\n"); + UnicodeUtils.escapeWithSpaces(hs, lvn.signature) + "\n");
} }
localVarTable = ctx.finish(); localVarTable = ctx.finish();
} else } else
@@ -427,8 +436,9 @@ public class Disassembler {
StringContext ctx = new StringContext(list.size() + 1); StringContext ctx = new StringContext(list.size() + 1);
ctx.next("\t// #TryCatch:\n"); ctx.next("\t// #TryCatch:\n");
for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) { for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) {
ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(tcbn.type) + " s:" + labels.get(tcbn.start.getLabel()) ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(hs, tcbn.type) + " s:"
+ " e:" + labels.get(tcbn.end.getLabel()) + " h:" + labels.get(tcbn.handler.getLabel()) + "\n"); + labels.get(tcbn.start.getLabel()) + " e:" + labels.get(tcbn.end.getLabel()) + " h:"
+ labels.get(tcbn.handler.getLabel()) + "\n");
} }
tryCatchTable = ctx.finish(); tryCatchTable = ctx.finish();
} else } else
@@ -436,7 +446,7 @@ public class Disassembler {
AbstractInsnNode[] insns = mn.instructions.toArray(); AbstractInsnNode[] insns = mn.instructions.toArray();
StringContext ctx = new StringContext(insns.length); StringContext ctx = new StringContext(insns.length);
for (AbstractInsnNode n : insns) { for (AbstractInsnNode n : insns) {
ctx.next(disassembleInstruction(n, labels)); ctx.next(disassembleInstruction(n, labels, hs));
} }
return new String[] { ctx.finish(), localVarTable, tryCatchTable }; return new String[] { ctx.finish(), localVarTable, tryCatchTable };
} }
@@ -444,17 +454,17 @@ public class Disassembler {
public static final HashMap<Class, InstructionInterface> iiMap = new HashMap<>(); public static final HashMap<Class, InstructionInterface> iiMap = new HashMap<>();
static { static {
iiMap.put(FieldInsnNode.class, (n, labels) -> { iiMap.put(FieldInsnNode.class, (n, labels, hs) -> {
FieldInsnNode node = (FieldInsnNode) n; FieldInsnNode node = (FieldInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/" + UnicodeUtils.escapeWithSpaces(hs, node.desc) + " " + UnicodeUtils.escapeWithSpaces(hs, node.owner)
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n"; + "/" + UnicodeUtils.escapeWithSpaces(hs, node.name).replace("/", "\\u002F") + "\n";
}); });
iiMap.put(LabelNode.class, (n, labels) -> { iiMap.put(LabelNode.class, (n, labels, hs) -> {
LabelNode node = (LabelNode) n; LabelNode node = (LabelNode) n;
return "\t\t// label " + labels.get(node.getLabel()) + "\n"; return "\t\t// label " + labels.get(node.getLabel()) + "\n";
}); });
iiMap.put(FrameNode.class, (n, labels) -> { iiMap.put(FrameNode.class, (n, labels, hs) -> {
FrameNode node = (FrameNode) n; FrameNode node = (FrameNode) n;
String type = ""; String type = "";
switch (node.type) { switch (node.type) {
@@ -485,7 +495,7 @@ public class Disassembler {
arr.add(null); arr.add(null);
} else { } else {
if (o instanceof String) { if (o instanceof String) {
arr.add("\"" + UnicodeUtils.escapeWithSpaces((String) o) + "\""); arr.add("\"" + UnicodeUtils.escapeWithSpaces(hs, (String) o) + "\"");
} else if (o instanceof LabelNode) { } else if (o instanceof LabelNode) {
arr.add("(label) " + labels.get(((LabelNode) o).getLabel())); arr.add("(label) " + labels.get(((LabelNode) o).getLabel()));
} else if (o instanceof Integer) { } else if (o instanceof Integer) {
@@ -511,7 +521,7 @@ public class Disassembler {
arr.add(null); arr.add(null);
} else { } else {
if (o instanceof String) { if (o instanceof String) {
arr.add("\"" + UnicodeUtils.escapeWithSpaces((String) o) + "\""); arr.add("\"" + UnicodeUtils.escapeWithSpaces(hs, (String) o) + "\"");
} else if (o instanceof LabelNode) { } else if (o instanceof LabelNode) {
arr.add("(label) " + labels.get(((LabelNode) o).getLabel())); arr.add("(label) " + labels.get(((LabelNode) o).getLabel()));
} else if (o instanceof Integer) { } else if (o instanceof Integer) {
@@ -532,18 +542,18 @@ public class Disassembler {
s += "\n"; s += "\n";
return s; return s;
}); });
iiMap.put(LineNumberNode.class, (n, labels) -> { iiMap.put(LineNumberNode.class, (n, labels, hs) -> {
LineNumberNode node = (LineNumberNode) n; LineNumberNode node = (LineNumberNode) n;
return "\t\t// line " + node.line + " " + labels.get(node.start.getLabel()) + "\n"; return "\t\t// line " + node.line + " " + labels.get(node.start.getLabel()) + "\n";
}); });
iiMap.put(InvokeDynamicInsnNode.class, (n, labels) -> { iiMap.put(InvokeDynamicInsnNode.class, (n, labels, hs) -> {
InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n; InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n;
String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: " String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: "
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n\t\t\tdesc: " + UnicodeUtils.escapeWithSpaces(hs, node.name).replace("/", "\\u002F") + "\n\t\t\tdesc: "
+ UnicodeUtils.escapeWithSpaces(node.desc) + "\n\t\t\tHandle: [\n\t\t\t\tname: " + UnicodeUtils.escapeWithSpaces(hs, node.desc) + "\n\t\t\tHandle: [\n\t\t\t\tname: "
+ UnicodeUtils.escapeWithSpaces(node.bsm.getName()) + "\n\t\t\t\towner: " + UnicodeUtils.escapeWithSpaces(hs, node.bsm.getName()) + "\n\t\t\t\towner: "
+ UnicodeUtils.escapeWithSpaces(node.bsm.getOwner()) + "\n\t\t\t\tdesc: " + UnicodeUtils.escapeWithSpaces(hs, node.bsm.getOwner()) + "\n\t\t\t\tdesc: "
+ UnicodeUtils.escapeWithSpaces(node.bsm.getDesc()) + "\n\t\t\t\tisInterface: " + UnicodeUtils.escapeWithSpaces(hs, node.bsm.getDesc()) + "\n\t\t\t\tisInterface: "
+ node.bsm.isInterface() + "\n\t\t\t\ttag: " + OpcodesReverse.reverseHandleOpcode(node.bsm.getTag()) + node.bsm.isInterface() + "\n\t\t\t\ttag: " + OpcodesReverse.reverseHandleOpcode(node.bsm.getTag())
+ "\n\t\t\t]\n\t\t\targs: [\n"; + "\n\t\t\t]\n\t\t\targs: [\n";
for (Object l : node.bsmArgs) { for (Object l : node.bsmArgs) {
@@ -555,40 +565,41 @@ public class Disassembler {
// Reflection // Reflection
s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type) s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type)
+ "\n\t\t\t\t\tstart: " + valueBegin + "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: " + "\n\t\t\t\t\tstart: " + valueBegin + "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: "
+ ClassUtil.getDecompiledValue(buf, ""); + ClassUtil.getDecompiledValue(buf, "", hs);
s += "\n\t\t\t\t]\n"; s += "\n\t\t\t\t]\n";
} else if (l instanceof Handle) { } else if (l instanceof Handle) {
Handle h = (Handle) l; Handle h = (Handle) l;
s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: " s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: "
+ UnicodeUtils.escapeWithSpaces(h.getName()).replace("/", "\\u002F") + "\n\t\t\t\t\towner: " + UnicodeUtils.escapeWithSpaces(hs, h.getName()).replace("/", "\\u002F")
+ UnicodeUtils.escapeWithSpaces(h.getOwner()) + "\n\t\t\t\t\tdesc: " + "\n\t\t\t\t\towner: " + UnicodeUtils.escapeWithSpaces(hs, h.getOwner())
+ UnicodeUtils.escapeWithSpaces(h.getDesc()) + "\n\t\t\t\t\tisInterface: " + h.isInterface() + "\n\t\t\t\t\tdesc: " + UnicodeUtils.escapeWithSpaces(hs, h.getDesc())
+ "\n\t\t\t\t\ttag: " + OpcodesReverse.reverseHandleOpcode(h.getTag()); + "\n\t\t\t\t\tisInterface: " + h.isInterface() + "\n\t\t\t\t\ttag: "
+ OpcodesReverse.reverseHandleOpcode(h.getTag());
s += "\n\t\t\t\t]\n"; s += "\n\t\t\t\t]\n";
} else { } else {
s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "") + "\n"; s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "", hs) + "\n";
} }
} }
s += "\t\t\t]\n\t\t]\n"; s += "\t\t\t]\n\t\t]\n";
return s; return s;
}); });
iiMap.put(MethodInsnNode.class, (n, labels) -> { iiMap.put(MethodInsnNode.class, (n, labels, hs) -> {
MethodInsnNode node = (MethodInsnNode) n; MethodInsnNode node = (MethodInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/" + UnicodeUtils.escapeWithSpaces(hs, node.desc) + " " + UnicodeUtils.escapeWithSpaces(hs, node.owner)
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n"; + "/" + UnicodeUtils.escapeWithSpaces(hs, node.name).replace("/", "\\u002F") + "\n";
}); });
iiMap.put(TypeInsnNode.class, (n, labels) -> { iiMap.put(TypeInsnNode.class, (n, labels, hs) -> {
TypeInsnNode node = (TypeInsnNode) n; TypeInsnNode node = (TypeInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
+ UnicodeUtils.escapeWithSpaces(node.desc) + "\n"; + UnicodeUtils.escapeWithSpaces(hs, node.desc) + "\n";
}); });
iiMap.put(MultiANewArrayInsnNode.class, (n, labels) -> { iiMap.put(MultiANewArrayInsnNode.class, (n, labels, hs) -> {
MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n; MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + node.dims + "\n"; + UnicodeUtils.escapeWithSpaces(hs, node.desc) + " " + node.dims + "\n";
}); });
iiMap.put(LdcInsnNode.class, (n, labels) -> { iiMap.put(LdcInsnNode.class, (n, labels, hs) -> {
LdcInsnNode node = (LdcInsnNode) n; LdcInsnNode node = (LdcInsnNode) n;
if (node.cst instanceof Type) { if (node.cst instanceof Type) {
Type type = (Type) node.cst; Type type = (Type) node.cst;
@@ -598,23 +609,23 @@ public class Disassembler {
// Reflection // Reflection
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: " String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: "
+ ClassUtil.getClassNameFromType(type) + "\n\t\t\tstart: " + valueBegin + "\n\t\t\tend: " + ClassUtil.getClassNameFromType(type) + "\n\t\t\tstart: " + valueBegin + "\n\t\t\tend: "
+ valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, ""); + valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, "", hs);
s += "\n\t\t]\n"; s += "\n\t\t]\n";
return s; return s;
} else { } else {
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
+ ClassUtil.getDecompiledValue(node.cst, "") + "\n"; + ClassUtil.getDecompiledValue(node.cst, "", hs) + "\n";
} }
}); });
iiMap.put(VarInsnNode.class, (n, labels) -> { iiMap.put(VarInsnNode.class, (n, labels, hs) -> {
VarInsnNode node = (VarInsnNode) n; VarInsnNode node = (VarInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + "\n"; return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + "\n";
}); });
iiMap.put(InsnNode.class, (n, labels) -> { iiMap.put(InsnNode.class, (n, labels, hs) -> {
InsnNode node = (InsnNode) n; InsnNode node = (InsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + "\n"; return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + "\n";
}); });
iiMap.put(IntInsnNode.class, (n, labels) -> { iiMap.put(IntInsnNode.class, (n, labels, hs) -> {
IntInsnNode node = (IntInsnNode) n; IntInsnNode node = (IntInsnNode) n;
if (n.getOpcode() == Opcodes.NEWARRAY) { if (n.getOpcode() == Opcodes.NEWARRAY) {
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
@@ -623,12 +634,12 @@ public class Disassembler {
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.operand + "\n"; return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.operand + "\n";
} }
}); });
iiMap.put(JumpInsnNode.class, (n, labels) -> { iiMap.put(JumpInsnNode.class, (n, labels, hs) -> {
JumpInsnNode node = (JumpInsnNode) n; JumpInsnNode node = (JumpInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + labels.get(node.label.getLabel()) return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + labels.get(node.label.getLabel())
+ "\n"; + "\n";
}); });
iiMap.put(TableSwitchInsnNode.class, (n, labels) -> { iiMap.put(TableSwitchInsnNode.class, (n, labels, hs) -> {
TableSwitchInsnNode node = (TableSwitchInsnNode) n; TableSwitchInsnNode node = (TableSwitchInsnNode) n;
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tmin: " + node.min String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tmin: " + node.min
+ "\n\t\t\tmax: " + node.max + "\n\t\t\tdefault: " + labels.get(node.dflt.getLabel()) + "\n\t\t\tmax: " + node.max + "\n\t\t\tdefault: " + labels.get(node.dflt.getLabel())
@@ -639,7 +650,7 @@ public class Disassembler {
s += "\t\t\t]\n\t\t]\n"; s += "\t\t\t]\n\t\t]\n";
return s; return s;
}); });
iiMap.put(LookupSwitchInsnNode.class, (n, labels) -> { iiMap.put(LookupSwitchInsnNode.class, (n, labels, hs) -> {
LookupSwitchInsnNode node = (LookupSwitchInsnNode) n; LookupSwitchInsnNode node = (LookupSwitchInsnNode) n;
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tdefault: " String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tdefault: "
+ labels.get(node.dflt.getLabel()) + "\n\t\t\tkeys: [\n"; + labels.get(node.dflt.getLabel()) + "\n\t\t\tkeys: [\n";
@@ -653,20 +664,20 @@ public class Disassembler {
s += "\t\t\t]\n\t\t]\n"; s += "\t\t\t]\n\t\t]\n";
return s; return s;
}); });
iiMap.put(IincInsnNode.class, (n, labels) -> { iiMap.put(IincInsnNode.class, (n, labels, hs) -> {
IincInsnNode node = (IincInsnNode) n; IincInsnNode node = (IincInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + " " + node.incr + "\n"; return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + " " + node.incr + "\n";
}); });
} }
static interface InstructionInterface { static interface InstructionInterface {
String apply(AbstractInsnNode n, HashMap<Label, Integer> labels); String apply(AbstractInsnNode n, HashMap<Label, Integer> labels, HugeStrings hs);
} }
public static String disassembleInstruction(AbstractInsnNode n, HashMap<Label, Integer> labels) { public static String disassembleInstruction(AbstractInsnNode n, HashMap<Label, Integer> labels, HugeStrings hs) {
InstructionInterface ii = iiMap.get(n.getClass()); InstructionInterface ii = iiMap.get(n.getClass());
if (ii != null) if (ii != null)
return ii.apply(n, labels); return ii.apply(n, labels, hs);
else else
return "\t\tNOT HANDLED! " + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " return "\t\tNOT HANDLED! " + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
+ n.getClass().getSimpleName() + "\n"; + n.getClass().getSimpleName() + "\n";
+53
View File
@@ -0,0 +1,53 @@
package me.ByteEdit.edit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import me.ByteEdit.utils.UnicodeUtils;
public class HugeStrings {
public static final int THRESHOLD = 1000;
private final HashMap<String, HugeData> map = new HashMap<>();
public String onString(String s) {
synchronized (map) {
HugeData i = map.get(s);
if (i == null)
map.put(s, i = new HugeData(map.size(), UnicodeUtils.escape(this, s, true)));
return "#" + Integer.toString(i.id);
}
}
public boolean isEmpty() {
return map.isEmpty();
}
public String makeStringsList() {
StringContext ctx = new StringContext(map.size());
List<HugeData> list = new ArrayList<>(map.values());
list.sort((o1, o2) -> Integer.compare(o1.id, o2.id));
for (HugeData hd : list) {
StringBuilder sb = new StringBuilder(20 + hd.escaped.length());
sb.append('#');
sb.append(Integer.toString(hd.id));
sb.append(": ");
sb.append(hd.escaped);
sb.append('\n');
ctx.next(sb.toString());
}
return ctx.finish();
}
private static class HugeData {
int id;
String escaped;
public HugeData(int id, String escaped) {
this.id = id;
this.escaped = escaped;
}
}
}
+20
View File
@@ -0,0 +1,20 @@
package me.ByteEdit.edit;
import java.util.HashMap;
public class HugeStringsRev {
private final HashMap<Integer, String> map = new HashMap<>();
public void add(int i, String s) {
map.put(Integer.valueOf(i), s);
}
public String get(int i) {
String s = map.get(Integer.valueOf(i));
if (s == null)
s = "#" + Integer.toString(i);
return s;
}
}
+9 -1
View File
@@ -16,8 +16,16 @@ public class StringContext {
arrs = new String[amt]; arrs = new String[amt];
} }
public void next(String s) { public int next(String s) {
int i = idx;
len += (arrs[idx++] = s).length(); len += (arrs[idx++] = s).length();
return i;
}
public void set(int i, String s) {
if (arrs[i] != null)
len -= arrs[i].length();
len += (arrs[i] = s).length();
} }
public String finish() { public String finish() {
+12 -10
View File
@@ -621,11 +621,11 @@ public class Main extends JFrame {
line = line.substring(2); line = line.substring(2);
if (line.startsWith("invoke")) { if (line.startsWith("invoke")) {
String[] split = line.split(" "); String[] split = line.split(" ");
String desc = UnicodeUtils.unescape(split[1]); String desc = UnicodeUtils.unescape(null, split[1], true);
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
String className = UnicodeUtils.unescape(target.substring(0, index)); String className = UnicodeUtils.unescape(null, target.substring(0, index), true);
String methodName = UnicodeUtils.unescape(target.substring(index + 1)); String methodName = UnicodeUtils.unescape(null, target.substring(index + 1), true);
ClassNode classNode = classNodes.get(getFullName(className)); ClassNode classNode = classNodes.get(getFullName(className));
if (classNode == null) { if (classNode == null) {
return; return;
@@ -644,7 +644,7 @@ public class Main extends JFrame {
} }
} else if (line.startsWith("new ")) { } else if (line.startsWith("new ")) {
String[] split = line.split(" "); String[] split = line.split(" ");
String className = UnicodeUtils.unescape(split[1]); String className = UnicodeUtils.unescape(null, split[1], true);
ClassNode classNode = classNodes.get(getFullName(className)); ClassNode classNode = classNodes.get(getFullName(className));
if (classNode == null) { if (classNode == null) {
return; return;
@@ -653,11 +653,11 @@ public class Main extends JFrame {
} else if (line.startsWith("getstatic ") || line.startsWith("putstatic ") || line.startsWith("getfield ") } else if (line.startsWith("getstatic ") || line.startsWith("putstatic ") || line.startsWith("getfield ")
|| line.startsWith("putfield ")) { || line.startsWith("putfield ")) {
String[] split = line.split(" "); String[] split = line.split(" ");
String desc = UnicodeUtils.unescape(split[1]); String desc = UnicodeUtils.unescape(null, split[1], true);
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
String className = UnicodeUtils.unescape(target.substring(0, index)); String className = UnicodeUtils.unescape(null, target.substring(0, index), true);
String fieldName = UnicodeUtils.unescape(target.substring(index + 1)); String fieldName = UnicodeUtils.unescape(null, target.substring(index + 1), true);
ClassNode classNode = classNodes.get(getFullName(className)); ClassNode classNode = classNodes.get(getFullName(className));
if (classNode == null) { if (classNode == null) {
return; return;
@@ -721,10 +721,12 @@ public class Main extends JFrame {
if (s.contains(" extends ")) if (s.contains(" extends "))
s = s.substring(0, s.lastIndexOf(" extends ")); s = s.substring(0, s.lastIndexOf(" extends "));
String[] split = s.split(" "); String[] split = s.split(" ");
String className = UnicodeUtils.unescape(split[split.length - 1]); String className = UnicodeUtils.unescape(null, split[split.length - 1], true);
renameBox.className = className; renameBox.className = className;
String name = UnicodeUtils.unescape(m.pattern() == renameableFieldPattern ? m.group(2) : m.group(1)); String name = UnicodeUtils.unescape(null, m.pattern() == renameableFieldPattern ? m.group(2) : m.group(1),
String desc = UnicodeUtils.unescape(m.pattern() == renameableFieldPattern ? m.group(1) : m.group(2)); true);
String desc = UnicodeUtils.unescape(null, m.pattern() == renameableFieldPattern ? m.group(1) : m.group(2),
true);
renameBox.name = name; renameBox.name = name;
renameBox.desc = desc; renameBox.desc = desc;
renameBox.txtName.setText(name); renameBox.txtName.setText(name);
+13 -10
View File
@@ -6,6 +6,8 @@ import java.util.HashSet;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import me.ByteEdit.edit.HugeStrings;
public class ClassUtil { public class ClassUtil {
public static final int ACC_PUBLIC = 0x0001; public static final int ACC_PUBLIC = 0x0001;
@@ -525,28 +527,29 @@ public class ClassUtil {
public static final HashMap<Class, DecompilationInterface> diMap = new HashMap<>(); public static final HashMap<Class, DecompilationInterface> diMap = new HashMap<>();
static { static {
diMap.put(String.class, (o, desc, escapeSpaces) -> "\"" diMap.put(String.class, (o, desc, escapeSpaces, hs) -> "\""
+ (escapeSpaces ? UnicodeUtils.escapeWithSpaces((String) o) : UnicodeUtils.escape((String) o)) + "\""); + (escapeSpaces ? UnicodeUtils.escapeWithSpaces(hs, (String) o) : UnicodeUtils.escape(hs, (String) o))
+ "\"");
diMap.put(Integer.class, diMap.put(Integer.class,
(o, desc, escape) -> desc.equals("Z") ? (((int) o) == 0 ? "false" : "true") : o.toString()); (o, desc, escape, hs) -> desc.equals("Z") ? (((int) o) == 0 ? "false" : "true") : o.toString());
diMap.put(Long.class, (o, desc, escape) -> o.toString() + "l"); diMap.put(Long.class, (o, desc, escape, hs) -> o.toString() + "l");
diMap.put(Float.class, (o, desc, escape) -> o.toString() + "f"); diMap.put(Float.class, (o, desc, escape, hs) -> o.toString() + "f");
} }
static interface DecompilationInterface { static interface DecompilationInterface {
String apply(Object o, String desc, boolean escape); String apply(Object o, String desc, boolean escape, HugeStrings hs);
} }
public static String getDecompiledValue(Object o, String desc, boolean escapeSpaces) { public static String getDecompiledValue(Object o, String desc, boolean escapeSpaces, HugeStrings hs) {
DecompilationInterface di = diMap.get(o.getClass()); DecompilationInterface di = diMap.get(o.getClass());
if (di != null) if (di != null)
return di.apply(o, desc, escapeSpaces); return di.apply(o, desc, escapeSpaces, hs);
else else
return o.toString(); return o.toString();
} }
public static String getDecompiledValue(Object o, String desc) { public static String getDecompiledValue(Object o, String desc, HugeStrings hs) {
return getDecompiledValue(o, desc, false); return getDecompiledValue(o, desc, false, hs);
} }
public static Object getCastedValue(String o, String className) { public static Object getCastedValue(String o, String className) {
+40 -5
View File
@@ -1,11 +1,26 @@
package me.ByteEdit.utils; package me.ByteEdit.utils;
import me.ByteEdit.edit.HugeStrings;
import me.ByteEdit.edit.HugeStringsRev;
public class UnicodeUtils { public class UnicodeUtils {
public static String unescape(String s) { public static String unescape(HugeStringsRev hsr, String s) {
return unescape(hsr, s, false);
}
public static String unescape(HugeStringsRev hsr, String s, boolean force) {
if (s == null) { if (s == null) {
return null; return null;
} }
if (!force && !s.isEmpty() && s.charAt(0) == '#' && s.length() < 12) {
try {
int id = Integer.parseInt(s.substring(1));
return hsr.get(id);
} catch (NumberFormatException ex) {
// Doesn't seem like a HugeString
}
}
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
char unicodeBuffer = 0; char unicodeBuffer = 0;
int stage = 0; int stage = 0;
@@ -78,10 +93,13 @@ public class UnicodeUtils {
return sb.toString(); return sb.toString();
} }
public static String escapeWithSpaces(String s) { public static String escapeWithSpaces(HugeStrings hs, String s) {
if (s == null) { if (s == null) {
return null; return null;
} }
if (s.length() > HugeStrings.THRESHOLD) {
return hs.onString(s);
}
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
char[] arr = s.toCharArray(); char[] arr = s.toCharArray();
int i = 0; int i = 0;
@@ -92,6 +110,9 @@ public class UnicodeUtils {
if (arr[0] == '/') { if (arr[0] == '/') {
sb.append("\\u002F"); sb.append("\\u002F");
i++; i++;
} else if (arr[0] == '#') {
sb.append("\\u0023");
i++;
} }
if (arr[len - 1] == '/') { if (arr[len - 1] == '/') {
addSlash = true; addSlash = true;
@@ -158,12 +179,26 @@ public class UnicodeUtils {
return sb.toString(); return sb.toString();
} }
public static String escape(String s) { public static String escape(HugeStrings hs, String s) {
return escape(hs, s, false);
}
public static String escape(HugeStrings hs, String s, boolean force) {
if (s == null) { if (s == null) {
return null; return null;
} }
StringBuilder sb = new StringBuilder(); if (!force && s.length() > HugeStrings.THRESHOLD) {
for (char c : s.toCharArray()) { return hs.onString(s);
}
char[] arr = s.toCharArray();
StringBuilder sb = new StringBuilder(arr.length);
int i = 0;
if (arr.length > 0 && arr[0] == '#') {
sb.append("\\u0023");
i++;
}
for (; i < arr.length; i++) {
char c = arr[i];
switch (c) { switch (c) {
case 'Ä': case 'Ä':
case 'ä': case 'ä':