001: /**
002: * YGuard -- an obfuscation library for Java(TM) classfiles.
003: *
004: * Original Copyright (c) 1999 Mark Welsh (markw@retrologic.com)
005: * Modifications Copyright (c) 2002 yWorks GmbH (yguard@yworks.com)
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * The author may be contacted at yguard@yworks.com
022: *
023: * Java and all Java-based marks are trademarks or registered
024: * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
025: */package com.yworks.yguard.obf.classfile;
026:
027: import java.io.*;
028: import com.yworks.yguard.ParseException;
029: import com.yworks.yguard.Conversion;
030:
031: /**
032: * Representation of an attribute. Specific attributes have their representations
033: * sub-classed from this.
034: *
035: * @author Mark Welsh
036: */
037: public class AttrInfo implements ClassConstants {
038: // Constants -------------------------------------------------------------
039: public static final int CONSTANT_FIELD_SIZE = 6;
040:
041: // Fields ----------------------------------------------------------------
042: private int u2attrNameIndex;
043: protected int u4attrLength;
044: private byte info[];
045:
046: protected ClassFile owner;
047:
048: // Class Methods ---------------------------------------------------------
049: /**
050: * Create a new AttrInfo from the data passed.
051: *
052: * @throws IOException if class file is corrupt or incomplete
053: */
054: public static AttrInfo create(DataInput din, ClassFile cf)
055: throws java.io.IOException {
056: if (din == null)
057: throw new NullPointerException(
058: "No input stream was provided.");
059:
060: // Instantiate based on attribute name
061: AttrInfo ai = null;
062: int attrNameIndex = din.readUnsignedShort();
063: int attrLength = din.readInt();
064: // byte[] buffer = new byte[attrLength];
065: // din.readFully(buffer);
066:
067: CpInfo cpInfo = cf.getCpEntry(attrNameIndex);
068: if (cpInfo instanceof Utf8CpInfo) {
069: String attrName = ((Utf8CpInfo) cpInfo).getString();
070: if (attrName.equals(ATTR_Code)) {
071: ai = new CodeAttrInfo(cf, attrNameIndex, attrLength);
072: } else if (attrName.equals(ATTR_ConstantValue)) {
073: ai = new ConstantValueAttrInfo(cf, attrNameIndex,
074: attrLength);
075: } else if (attrName.equals(ATTR_Exceptions)) {
076: ai = new ExceptionsAttrInfo(cf, attrNameIndex,
077: attrLength);
078: } else if (attrName.equals(ATTR_StackMapTable)) {
079: ai = new StackMapTableAttrInfo(cf, attrNameIndex,
080: attrLength);
081: } else if (attrName.equals(ATTR_LineNumberTable)) {
082: ai = new LineNumberTableAttrInfo(cf, attrNameIndex,
083: attrLength);
084: } else if (attrName.equals(ATTR_SourceFile)) {
085: ai = new SourceFileAttrInfo(cf, attrNameIndex,
086: attrLength);
087: } else if (attrName.equals(ATTR_LocalVariableTable)) {
088: ai = new LocalVariableTableAttrInfo(cf, attrNameIndex,
089: attrLength);
090: } else if (attrName.equals(ATTR_InnerClasses)) {
091: ai = new InnerClassesAttrInfo(cf, attrNameIndex,
092: attrLength);
093: } else if (attrName.equals(ATTR_Synthetic)) {
094: ai = new SyntheticAttrInfo(cf, attrNameIndex,
095: attrLength);
096: } else if (attrName.equals(ATTR_Deprecated)) {
097: ai = new DeprecatedAttrInfo(cf, attrNameIndex,
098: attrLength);
099: } else if (attrName.equals(ATTR_Signature)) {
100: ai = new SignatureAttrInfo(cf, attrNameIndex,
101: attrLength);
102: } else if (attrName.equals(ATTR_LocalVariableTypeTable)) {
103: ai = new LocalVariableTypeTableAttrInfo(cf,
104: attrNameIndex, attrLength);
105: } else if (attrName.equals(ATTR_EnclosingMethod)) {
106: ai = new EnclosingMethodAttrInfo(cf, attrNameIndex,
107: attrLength);
108: } else if (attrName.equals(ATTR_RuntimeVisibleAnnotations)) {
109: ai = new RuntimeVisibleAnnotationsAttrInfo(cf,
110: attrNameIndex, attrLength);
111: } else if (attrName
112: .equals(ATTR_RuntimeInvisibleAnnotations)) {
113: ai = new RuntimeInvisibleAnnotationsAttrInfo(cf,
114: attrNameIndex, attrLength);
115: } else if (attrName
116: .equals(ATTR_RuntimeVisibleParameterAnnotations)) {
117: ai = new RuntimeVisibleParameterAnnotationsAttrInfo(cf,
118: attrNameIndex, attrLength);
119: } else if (attrName
120: .equals(ATTR_RuntimeInvisibleParameterAnnotations)) {
121: ai = new RuntimeInvisibleParameterAnnotationsAttrInfo(
122: cf, attrNameIndex, attrLength);
123: } else if (attrName.equals(ATTR_AnnotationDefault)) {
124: ai = new AnnotationDefaultAttrInfo(cf, attrNameIndex,
125: attrLength);
126: } else if (attrName.equals(ATTR_Bridge)
127: && (attrLength == 0)) {
128: ai = new AttrInfo(cf, attrNameIndex, attrLength);
129: } else if (attrName.equals(ATTR_Enum) && (attrLength == 0)) {
130: ai = new AttrInfo(cf, attrNameIndex, attrLength);
131: } else if (attrName.equals(ATTR_Varargs)
132: && (attrLength == 0)) {
133: ai = new AttrInfo(cf, attrNameIndex, attrLength);
134: } else {
135: if (attrLength > 0) {
136: Logger.getInstance().warning(
137: "Unrecognized attribute '"
138: + attrName
139: + "' in "
140: + Conversion.toJavaClass(cf
141: .getName()));
142: }
143: ai = new AttrInfo(cf, attrNameIndex, attrLength);
144: }
145: } else {
146: throw new ParseException(
147: "Inconsistent reference to Constant Pool.");
148: }
149:
150: // ai.readInfo(new DataInputStream(new ByteArrayInputStream(buffer)));
151: ai.readInfo(din);
152: return ai;
153: }
154:
155: // Instance Methods ------------------------------------------------------
156: protected AttrInfo(ClassFile cf, int attrNameIndex, int attrLength) {
157: owner = cf;
158: u2attrNameIndex = attrNameIndex;
159: u4attrLength = attrLength;
160: }
161:
162: protected int getAttrNameIndex() {
163: return u2attrNameIndex;
164: }
165:
166: /** Return the length in bytes of the attribute; over-ride this in sub-classes. */
167: protected int getAttrInfoLength() {
168: return u4attrLength;
169: }
170:
171: /** Return the String name of the attribute; over-ride this in sub-classes. */
172: protected String getAttrName() {
173: return ATTR_Unknown;
174: }
175:
176: /**
177: * Trim attributes from the classfile except those in the String[].
178: */
179: protected void trimAttrsExcept(String[] keepAttrs) {
180: }
181:
182: /** Check for Utf8 references to constant pool and mark them. */
183: protected void markUtf8Refs(ConstantPool pool) {
184: pool.incRefCount(u2attrNameIndex);
185: markUtf8RefsInInfo(pool);
186: }
187:
188: /**
189: * Check for Utf8 references in the 'info' data to the constant pool and
190: * mark them; over-ride this in sub-classes.
191: */
192: protected void markUtf8RefsInInfo(ConstantPool pool) {
193: }
194:
195: /** Read the data following the header; over-ride this in sub-classes. */
196: protected void readInfo(DataInput din) throws java.io.IOException {
197: info = new byte[u4attrLength];
198: din.readFully(info);
199: }
200:
201: /** Export the representation to a DataOutput stream. */
202: public final void write(DataOutput dout) throws java.io.IOException {
203: if (dout == null)
204: throw new IOException("No output stream was provided.");
205: dout.writeShort(u2attrNameIndex);
206: dout.writeInt(getAttrInfoLength());
207: writeInfo(dout);
208: }
209:
210: /** Export data following the header to a DataOutput stream; over-ride this in sub-classes. */
211: public void writeInfo(DataOutput dout) throws java.io.IOException {
212: dout.write(info);
213: }
214:
215: public String toString() {
216: return getAttrName() + "[" + getAttrInfoLength() + "]";
217: }
218: }
|