home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2003 January / maximum-cd-2003-01.iso / Software / Apps / OperawithJava / ow32enen700b1j.exe / OPERA.JAR / opera / Broken11ClassFixer.class (.txt) < prev    next >
Encoding:
Java Class File  |  2002-11-05  |  6.7 KB  |  396 lines

  1. package opera;
  2.  
  3. import java.io.BufferedInputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.lang.reflect.Modifier;
  7.  
  8. class Broken11ClassFixer {
  9.    private byte[] src;
  10.    private int srcPos;
  11.    private byte[] dest;
  12.    private int destPos;
  13.    private int numConstantPoolEntries;
  14.    private boolean detectedBogusLocalVariableNameIndex;
  15.    private static final int CODE_MASK = 1;
  16.    private static final int LOCAL_VARIABLE_TABLE_MASK = 2;
  17.    private byte[] constantPoolUtf8Entries;
  18.    private static final int CONSTANT_CLASS_TAG = 7;
  19.    private static final int CONSTANT_FIELD_REF_TAG = 9;
  20.    private static final int CONSTANT_METHOD_REF_TAG = 10;
  21.    private static final int CONSTANT_INTERFACE_METHOD_REF_TAG = 11;
  22.    private static final int CONSTANT_STRING_TAG = 8;
  23.    private static final int CONSTANT_INTEGER_TAG = 3;
  24.    private static final int CONSTANT_FLOAT_TAG = 4;
  25.    private static final int CONSTANT_LONG_TAG = 5;
  26.    private static final int CONSTANT_DOUBLE_TAG = 6;
  27.    private static final int CONSTANT_NAME_AND_TYPE_TAG = 12;
  28.    private static final int CONSTANT_UTF8_TAG = 1;
  29.  
  30.    public Broken11ClassFixer() {
  31.    }
  32.  
  33.    public void process(byte[] var1, int var2, int var3) throws Exception {
  34.       this.init(var1, var2, var3);
  35.       this.copyHeader();
  36.       this.scanAndCopyConstantPool();
  37.       this.copyAccessFlagsAndClassInformation();
  38.       this.copyInterfaces();
  39.       this.scanAndCopyFields();
  40.       this.scanAndCopyMethods();
  41.       this.copyAttributes();
  42.    }
  43.  
  44.    public byte[] getProcessedData() {
  45.       return this.dest;
  46.    }
  47.  
  48.    public int getProcessedDataOffset() {
  49.       return 0;
  50.    }
  51.  
  52.    public int getProcessedDataLength() {
  53.       return this.destPos;
  54.    }
  55.  
  56.    private void init(byte[] var1, int var2, int var3) {
  57.       this.src = var1;
  58.       this.srcPos = var2;
  59.       this.dest = new byte[var3];
  60.       this.destPos = 0;
  61.       this.detectedBogusLocalVariableNameIndex = false;
  62.    }
  63.  
  64.    private int srcPos() {
  65.       return this.srcPos;
  66.    }
  67.  
  68.    private int destPos() {
  69.       return this.destPos;
  70.    }
  71.  
  72.    private int readByte() {
  73.       return this.src[this.srcPos++] & 255;
  74.    }
  75.  
  76.    private int readShort() {
  77.       int var1 = this.readByte();
  78.       int var2 = this.readByte();
  79.       return var1 << 8 | var2;
  80.    }
  81.  
  82.    private int readInt() {
  83.       int var1 = this.readShort();
  84.       int var2 = this.readShort();
  85.       return var1 << 16 | var2;
  86.    }
  87.  
  88.    private void writeByte(int var1) {
  89.       this.dest[this.destPos++] = (byte)var1;
  90.    }
  91.  
  92.    private void writeShort(int var1) {
  93.       this.writeByte(var1 >> 8);
  94.       this.writeByte(var1);
  95.    }
  96.  
  97.    private void writeInt(int var1) {
  98.       this.writeShort(var1 >> 16);
  99.       this.writeShort(var1);
  100.    }
  101.  
  102.    private void writeByteAt(int var1, int var2) {
  103.       this.dest[var1] = (byte)var2;
  104.    }
  105.  
  106.    private void writeShortAt(int var1, int var2) {
  107.       this.writeByteAt(var1, var2 >> 8);
  108.       this.writeByteAt(var1 + 1, var2);
  109.    }
  110.  
  111.    private void writeIntAt(int var1, int var2) {
  112.       this.writeShortAt(var1, var2 >> 16);
  113.       this.writeShortAt(var1 + 2, var2);
  114.    }
  115.  
  116.    private void copy(int var1) {
  117.       for(int var2 = 0; var2 < var1; ++var2) {
  118.          this.dest[this.destPos + var2] = this.src[this.srcPos + var2];
  119.       }
  120.  
  121.       this.srcPos += var1;
  122.       this.destPos += var1;
  123.    }
  124.  
  125.    private int copyByte() {
  126.       int var1 = this.readByte();
  127.       this.writeByte(var1);
  128.       return var1;
  129.    }
  130.  
  131.    private int copyShort() {
  132.       int var1 = this.readShort();
  133.       this.writeShort(var1);
  134.       return var1;
  135.    }
  136.  
  137.    private int copyInt() {
  138.       int var1 = this.readInt();
  139.       this.writeInt(var1);
  140.       return var1;
  141.    }
  142.  
  143.    private void copyHeader() {
  144.       this.copy(8);
  145.    }
  146.  
  147.    private void scanAndCopyConstantPool() {
  148.       this.numConstantPoolEntries = this.copyShort() - 1;
  149.       this.constantPoolUtf8Entries = new byte[this.numConstantPoolEntries];
  150.  
  151.       for(int var1 = 0; var1 < this.numConstantPoolEntries; ++var1) {
  152.          int var2 = this.copyByte();
  153.          switch (var2) {
  154.             case 1:
  155.                this.scanAndCopyUtf8(var1);
  156.                break;
  157.             case 2:
  158.             default:
  159.                throw new RuntimeException("Invalid constant pool tag " + var2);
  160.             case 3:
  161.             case 4:
  162.             case 9:
  163.             case 10:
  164.             case 11:
  165.             case 12:
  166.                this.copy(4);
  167.                break;
  168.             case 5:
  169.             case 6:
  170.                this.copy(8);
  171.                ++var1;
  172.                break;
  173.             case 7:
  174.             case 8:
  175.                this.copy(2);
  176.          }
  177.       }
  178.  
  179.    }
  180.  
  181.    private void scanAndCopyUtf8(int var1) {
  182.       int var2 = this.copyShort();
  183.       String var3 = "Code";
  184.       String var4 = "LocalVariableTable";
  185.       if (var2 == var3.length()) {
  186.          if (this.copyUtf8LookingFor(var3)) {
  187.             this.markCodeInCP(var1);
  188.          }
  189.       } else if (var2 == var4.length()) {
  190.          if (this.copyUtf8LookingFor(var4)) {
  191.             this.markLocalVariableTableInCP(var1);
  192.          }
  193.       } else {
  194.          this.copy(var2);
  195.       }
  196.  
  197.    }
  198.  
  199.    private boolean copyUtf8LookingFor(String var1) {
  200.       int var2 = var1.length();
  201.  
  202.       for(int var3 = 0; var3 < var2; ++var3) {
  203.          int var4 = this.copyByte();
  204.          if (var4 != (var1.charAt(var3) & 255)) {
  205.             this.copy(var2 - var3 - 1);
  206.             return false;
  207.          }
  208.       }
  209.  
  210.       return true;
  211.    }
  212.  
  213.    private void markCodeInCP(int var1) {
  214.       byte[] var10000 = this.constantPoolUtf8Entries;
  215.       var10000[var1] = (byte)(var10000[var1] | 1);
  216.    }
  217.  
  218.    private void markLocalVariableTableInCP(int var1) {
  219.       byte[] var10000 = this.constantPoolUtf8Entries;
  220.       var10000[var1] = (byte)(var10000[var1] | 2);
  221.    }
  222.  
  223.    private void copyAccessFlagsAndClassInformation() {
  224.       this.copy(6);
  225.    }
  226.  
  227.    private void copyInterfaces() {
  228.       int var1 = this.copyShort();
  229.       this.copy(2 * var1);
  230.    }
  231.  
  232.    private void scanAndCopyFields() {
  233.       int var1 = this.copyShort();
  234.  
  235.       for(int var2 = 0; var2 < var1; ++var2) {
  236.          this.scanAndCopyAccessFlags();
  237.          this.copy(4);
  238.          this.copyAttributes();
  239.       }
  240.  
  241.    }
  242.  
  243.    private void scanAndCopyAccessFlags() {
  244.       int var1 = this.readShort();
  245.       if (Modifier.isPublic(var1)) {
  246.          var1 &= -7;
  247.       } else if (Modifier.isProtected(var1)) {
  248.          var1 &= -4;
  249.       } else {
  250.          var1 &= -6;
  251.       }
  252.  
  253.       this.writeShort(var1);
  254.    }
  255.  
  256.    private boolean cpIdxIsLocalVariableTable(int var1) {
  257.       return (this.constantPoolUtf8Entries[var1 - 1] & 2) != 0;
  258.    }
  259.  
  260.    private boolean cpIdxIsCode(int var1) {
  261.       return (this.constantPoolUtf8Entries[var1 - 1] & 1) != 0;
  262.    }
  263.  
  264.    private boolean isValidConstantPoolIndex(int var1) {
  265.       return var1 > 0 && var1 <= this.numConstantPoolEntries;
  266.    }
  267.  
  268.    private boolean isValidStartAndLength(int var1, int var2, int var3) {
  269.       return var1 >= 0 && var1 + var2 <= var3;
  270.    }
  271.  
  272.    private void copyAttributes() {
  273.       int var1 = this.copyShort();
  274.  
  275.       for(int var2 = 0; var2 < var1; ++var2) {
  276.          this.copyAttribute();
  277.       }
  278.  
  279.    }
  280.  
  281.    private void copyAttribute() {
  282.       this.copy(2);
  283.       this.copyRestOfAttribute();
  284.    }
  285.  
  286.    private void copyRestOfAttribute() {
  287.       this.copy(this.copyInt());
  288.    }
  289.  
  290.    private void scanAndCopyMethods() {
  291.       int var1 = this.copyShort();
  292.  
  293.       for(int var2 = 0; var2 < var1; ++var2) {
  294.          this.scanAndCopyAccessFlags();
  295.          this.copy(4);
  296.          int var3 = this.copyShort();
  297.  
  298.          for(int var4 = 0; var4 < var3; ++var4) {
  299.             int var5 = this.copyShort();
  300.             if (this.cpIdxIsCode(var5)) {
  301.                this.processCodeAttribute();
  302.             } else {
  303.                this.copyRestOfAttribute();
  304.             }
  305.          }
  306.       }
  307.  
  308.    }
  309.  
  310.    private void processCodeAttribute() {
  311.       int var1 = this.destPos();
  312.       int var2 = this.copyInt();
  313.       this.copy(4);
  314.       int var3 = this.copyInt();
  315.       this.copy(var3);
  316.       this.copy(8 * this.copyShort());
  317.       int var4 = this.copyShort();
  318.  
  319.       for(int var5 = 0; var5 < var4; ++var5) {
  320.          int var6 = this.copyShort();
  321.          if (this.cpIdxIsLocalVariableTable(var6)) {
  322.             this.processLocalVariableTableAttribute(var1, var2, var3);
  323.          } else {
  324.             this.copyRestOfAttribute();
  325.          }
  326.       }
  327.  
  328.    }
  329.  
  330.    private void processLocalVariableTableAttribute(int var1, int var2, int var3) {
  331.       int var4 = this.destPos();
  332.       int var5 = this.copyInt();
  333.       int var6 = this.destPos();
  334.       int var7 = this.copyShort();
  335.       int var8 = var7;
  336.  
  337.       for(int var10 = 0; var10 < var7; ++var10) {
  338.          int var11 = this.readShort();
  339.          int var12 = this.readShort();
  340.          int var13 = this.readShort();
  341.          int var14 = this.readShort();
  342.          int var15 = this.readShort();
  343.          if (this.isValidConstantPoolIndex(var13) && this.isValidStartAndLength(var11, var12, var3)) {
  344.             this.writeShort(var11);
  345.             this.writeShort(var12);
  346.             this.writeShort(var13);
  347.             this.writeShort(var14);
  348.             this.writeShort(var15);
  349.          } else {
  350.             var2 -= 10;
  351.             var5 -= 10;
  352.             --var8;
  353.             this.writeIntAt(var1, var2);
  354.             this.writeIntAt(var4, var5);
  355.             this.writeShortAt(var6, var8);
  356.             this.detectedBogusLocalVariableNameIndex = true;
  357.          }
  358.       }
  359.  
  360.    }
  361.  
  362.    private static void usage() {
  363.       System.err.println("Usage: java Broken11ClassFixer [filename]");
  364.       System.exit(1);
  365.    }
  366.  
  367.    public static void main(String[] var0) {
  368.       if (var0.length != 1) {
  369.          usage();
  370.       }
  371.  
  372.       try {
  373.          File var1 = new File(var0[0]);
  374.          int var2 = (int)var1.length();
  375.          byte[] var3 = new byte[var2];
  376.          BufferedInputStream var4 = new BufferedInputStream(new FileInputStream(var1));
  377.  
  378.          for(int var5 = 0; var5 < var3.length; var5 += var4.read(var3, var5, var3.length - var5)) {
  379.          }
  380.  
  381.          Broken11ClassFixer var6 = new Broken11ClassFixer();
  382.          var6.process(var3, 0, var3.length);
  383.          if (var6.detectedBogusLocalVariableNameIndex) {
  384.             System.err.println("Detected bogus local variable name index");
  385.          }
  386.  
  387.          if (var6.srcPos < var3.length) {
  388.             System.err.println("Detected extra bytes at the end of the class file");
  389.          }
  390.       } catch (Exception var7) {
  391.          var7.printStackTrace();
  392.       }
  393.  
  394.    }
  395. }
  396.