From eba64de0146cf52f806314f7fd1c954d722595f2 Mon Sep 17 00:00:00 2001 From: chibash Date: Fri, 13 May 2022 01:33:19 +0900 Subject: [PATCH] fixes a bug in SignatureAttribute.renameClass(). --- .../bytecode/SignatureAttribute.java | 120 +++++++++++------- 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/src/main/javassist/bytecode/SignatureAttribute.java b/src/main/javassist/bytecode/SignatureAttribute.java index c17b3f29..37eec07f 100644 --- a/src/main/javassist/bytecode/SignatureAttribute.java +++ b/src/main/javassist/bytecode/SignatureAttribute.java @@ -131,64 +131,96 @@ public class SignatureAttribute extends AttributeInfo { try { while ((c = desc.charAt(++k)) != ';') { if (c == '<') { - genericParamBuf.append(c); - int level = 1; + genericParamBuf.append(c); + int level = 1; while (level > 0) { - c = desc.charAt(++k); - genericParamBuf.append(c); - if (c == '<') ++level; - else if (c == '>') --level; + c = desc.charAt(++k); + genericParamBuf.append(c); + if (c == '<') + ++level; + else if (c == '>') + --level; } - } else if (c == '.') { - nameBufs.add(nameBuf); - genericParamBufs.add(genericParamBuf); - nameBuf = new StringBuilder(); - genericParamBuf = new StringBuilder(); - } else { - nameBuf.append(c); } + else if (c == '.') { + nameBufs.add(nameBuf); + genericParamBufs.add(genericParamBuf); + nameBuf = new StringBuilder(); + genericParamBuf = new StringBuilder(); + } + else + nameBuf.append(c); } } catch (IndexOutOfBoundsException e) { break; } nameBufs.add(nameBuf); - genericParamBufs.add(genericParamBuf); + genericParamBufs.add(genericParamBuf); i = k + 1; - + String name = String.join("$", nameBufs.toArray(new StringBuilder[0])); String newname = map.get(name); if (newname != null) { final String[] nameSplit = name.split("\\$"); final String[] newnameSplit = newname.split("\\$"); - if (nameSplit.length == newnameSplit.length) { - final String[] newnames = new String[nameBufs.size()]; - for (int start = 0, z = 0; z < nameBufs.size(); ++z) { - final int toAggregate = (int) nameBufs.get(z).chars().filter(ch -> ch == '$').count() + 1; - String s = String.join("$", Arrays.copyOfRange(newnameSplit, start, start + toAggregate)); - start += toAggregate; - newnames[z] = s; - } - - - newdesc.append(desc.substring(head, j)); - newdesc.append('L'); - for (int z = 0; z < newnames.length; ++z) { - if (z > 0) { - newdesc.append('.'); - } - newdesc.append(newnames[z]); - final String newgenericParam; - final StringBuilder genericParamBufCurrent = genericParamBufs.get(z); - if (genericParamBufCurrent.length() > 0) { - newgenericParam = "<" + renameClass(genericParamBufCurrent.substring(1, genericParamBufCurrent.length() - 1), map) + ">"; - } else { - newgenericParam = genericParamBufCurrent.toString(); //empty string - } - newdesc.append(newgenericParam); - } - newdesc.append(c); //the final semicolon - head = i; - } + if (nameSplit.length == newnameSplit.length) { + final String[] newnames = new String[nameBufs.size()]; + for (int start = 0, z = 0; z < nameBufs.size(); z++) { + final int toAggregate = (int) nameBufs.get(z).chars().filter(ch -> ch == '$').count() + 1; + String s = String.join("$", Arrays.copyOfRange(newnameSplit, start, start + toAggregate)); + start += toAggregate; + newnames[z] = s; + } + + newdesc.append(desc.substring(head, j)); + newdesc.append('L'); + for (int z = 0; z < newnames.length; z++) { + if (z > 0) + newdesc.append('.'); + + newdesc.append(newnames[z]); + final String newgenericParam; + final StringBuilder genericParamBufCurrent = genericParamBufs.get(z); + if (genericParamBufCurrent.length() > 0) + newgenericParam = "<" + renameClass(genericParamBufCurrent.substring(1, genericParamBufCurrent.length() - 1), map) + ">"; + else + newgenericParam = genericParamBufCurrent.toString(); //empty string + + newdesc.append(newgenericParam); + } + newdesc.append(c); //the final semicolon + head = i; + } + } + else { + final ArrayList newGenericParamBufs = new ArrayList(); + boolean changed = false; + for (int z = 0; z < genericParamBufs.size(); z++) { + final String newGenericParam; + final StringBuilder genericParamBufCurrent = genericParamBufs.get(z); + if (genericParamBufCurrent.length() > 0) { + newGenericParam = "<" + renameClass(genericParamBufCurrent.substring(1, genericParamBufCurrent.length() - 1), map) + ">"; + changed = changed || !genericParamBufCurrent.toString().equals(newGenericParam); + } + else + newGenericParam = genericParamBufCurrent.toString(); //empty string + + newGenericParamBufs.add(newGenericParam); + } + + if (changed) { + newdesc.append(desc.substring(head, j)); + newdesc.append('L'); + for (int z = 0; z < genericParamBufs.size(); z++) { + if (z > 0) + newdesc.append('.'); + + newdesc.append(nameBufs.get(z)); + newdesc.append(newGenericParamBufs.get(z)); + } + newdesc.append(';'); + head = i; + } } } -- 2.39.5