You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by dj...@apache.org on 2005/04/07 20:31:37 UTC

svn commit: r160426 - incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect

Author: djd
Date: Thu Apr  7 11:31:35 2005
New Revision: 160426

URL: http://svn.apache.org/viewcvs?view=rev&rev=160426
Log:
Derby-176 (partial) - Added checks when the generated class file's format is created
to ensure the structure is not corrupted by writing truncated values.
E.g. a constant pool count N with N >65535 now will throw an error rather
than generate a class file with an apparent constant pool count of N % 65535.

Modified:
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassFormatOutput.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassHolder.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/GClass.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassFormatOutput.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassFormatOutput.java?view=diff&r1=160425&r2=160426
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassFormatOutput.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassFormatOutput.java Thu Apr  7 11:31:35 2005
@@ -50,9 +50,22 @@
 	}
 
 	public void putU1(int i) throws IOException {
+		// ensure the format of the class file is not
+		// corrupted by writing an incorrect, truncated value.
+		if (i > 255)
+			ClassFormatOutput.limit("U1", 255, i);
 		write(i);
 	}
 	public void putU2(int i) throws IOException {
+		putU2("U2", i);
+
+	}
+	public void putU2(String limit, int i) throws IOException {
+		
+		// ensure the format of the class file is not
+		// corrupted by writing an incorrect, truncated value.
+		if (i > 65535)
+			ClassFormatOutput.limit(limit, 65535, i);
 		write(i >> 8);
 		write(i);
 	}
@@ -70,5 +83,18 @@
 	*/
 	public byte[] getData() {
 		return ((AccessibleByteArrayOutputStream) out).getInternalByteArray();
+	}
+
+	/**
+	 * Throw an ClassFormatError if a limit of the Java class file format is reached.
+	 * @param name Terse limit description from JVM spec.
+	 * @param limit What the limit is.
+	 * @param value What the value for the current class is
+	 * @throws IOException Thrown when limit is exceeded.
+	 */
+	static void limit(String name, int limit, int value)
+		throws IOException
+	{
+		throw new IOException(name + "(" + value + " > " + limit + ")");
 	}
 }

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassHolder.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassHolder.java?view=diff&r1=160425&r2=160426
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassHolder.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/classfile/ClassHolder.java Thu Apr  7 11:31:35 2005
@@ -113,14 +113,19 @@
 		method_info = new MemberTable(0);
 	}
 
-	public void put(ClassFormatOutput out) throws IOException {
+	private void put(ClassFormatOutput out) throws IOException {
 
 		/* Write out the header */
 		out.putU4(VMDescriptor.JAVA_CLASS_FORMAT_MAGIC);
 		out.putU2(VMDescriptor.JAVA_CLASS_FORMAT_MINOR_VERSION);
 		out.putU2(VMDescriptor.JAVA_CLASS_FORMAT_MAJOR_VERSION);
 
-		out.putU2(cptEntries.size());
+		// special case checking that the number of constant
+		// pool entries does not exceed the limit of 65535
+		// (as it is stored as a U2).
+		// Special case to allow somewhat easier debugging
+		// of the resulting failure.
+		out.putU2("constant_pool", cptEntries.size());
 		cptPut(out);
 
 		out.putU2(access_flags);
@@ -165,8 +170,12 @@
 	**	Public methods from ClassHolder.
 	*/
 
-
-	public ByteArray getFileFormat() {
+	/**
+	 * Convert the object representation of the class into
+	 * its class file format.
+	 * @exception IOException error writing the class
+	 */
+	public ByteArray getFileFormat() throws IOException {
 
 		int classFileSize = 4 + (10 * 2);
 		classFileSize += cptEstimatedSize;
@@ -183,16 +192,12 @@
 		if (attribute_info != null)
 			classFileSize += attribute_info.classFileSize();
 
-		try {
-			ClassFormatOutput cfo = new ClassFormatOutput(classFileSize + 200);
-
-			put(cfo);
+	
+		ClassFormatOutput cfo = new ClassFormatOutput(classFileSize + 200);
 
-			return new ByteArray(cfo.getData(), 0, cfo.size());
+		put(cfo);
 
-		} catch (IOException e) {
-			return null;
-		}
+		return new ByteArray(cfo.getData(), 0, cfo.size());
 
 	}
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java?view=diff&r1=160425&r2=160426
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java Thu Apr  7 11:31:35 2005
@@ -84,7 +84,7 @@
 	 * generated, if there are no constructors then
 	 * the default no-arg constructor will be defined.
 	 */
-	ByteArray getClassBytecode();
+	ByteArray getClassBytecode() throws StandardException;
 
 	/**
 	 * the class's unqualified name

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java?view=diff&r1=160425&r2=160426
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java Thu Apr  7 11:31:35 2005
@@ -31,7 +31,9 @@
 
 import org.apache.derby.iapi.services.monitor.Monitor;
 
+import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.reference.Property;
+import org.apache.derby.iapi.reference.SQLState;
 
 import org.apache.derby.iapi.util.ByteArray;
 import org.apache.derby.iapi.services.classfile.VMOpcode;
@@ -105,32 +107,33 @@
 	 * generated, if there are no constructors then
 	 * the default no-arg constructor will be defined.
 	 */
-	public ByteArray getClassBytecode() {
+	public ByteArray getClassBytecode() throws StandardException {
 
 		// return if already done
 		if (bytecode != null) return bytecode;
+		
+		try {
 
-		if (SanityManager.DEBUG) {
-		  if (SanityManager.DEBUG_ON("ClassLineNumbers")) {
+			if (SanityManager.DEBUG) {
+				if (SanityManager.DEBUG_ON("ClassLineNumbers")) {
 
-			try {
+					ClassFormatOutput sout = new ClassFormatOutput(2);
 
-				ClassFormatOutput sout = new ClassFormatOutput(2);
+					int cpiUTF = classHold.addUtf8("GC.java");
 
-				int cpiUTF = classHold.addUtf8("GC.java");
+					sout.putU2(cpiUTF);
 
-				sout.putU2(cpiUTF);
-
-				classHold.addAttribute("SourceFile", sout);
-			} catch (IOException ioe) {
-				SanityManager.THROWASSERT("i/o exception generating class file " + ioe.toString());
+					classHold.addAttribute("SourceFile", sout);
+				}
 			}
-		  }
-		}
 
-
-		// the class is now complete, get its bytecode.
-		bytecode = classHold.getFileFormat();
+			// the class is now complete, get its bytecode.
+			bytecode = classHold.getFileFormat();
+			
+		} catch (IOException ioe) {
+			throw StandardException.newException(
+					SQLState.GENERATED_CLASS_LINKAGE_ERROR, ioe, getFullName());
+		}
 
 		// release resources, we have the code now.
 		// name is not released, it may still be accessed.

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/GClass.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/GClass.java?view=diff&r1=160425&r2=160426
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/GClass.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/GClass.java Thu Apr  7 11:31:35 2005
@@ -59,7 +59,8 @@
 		return cf.loadGeneratedClass(qualifiedName, getClassBytecode());
 	}
 
-	protected void writeClassFile(String dir, boolean logMessage, Throwable t) {
+	protected void writeClassFile(String dir, boolean logMessage, Throwable t)
+		throws StandardException {
 
 		if (SanityManager.DEBUG) {
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java?view=diff&r1=160425&r2=160426
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java Thu Apr  7 11:31:35 2005
@@ -263,7 +263,8 @@
 		return -1;
 	}
 
-	public ByteArray buildSpecificFactory(String className, String factoryName) {
+	public ByteArray buildSpecificFactory(String className, String factoryName)
+		throws StandardException {
 
 		ClassBuilder cb = javaFactory.newClassBuilder(this, CodeGeneration.GENERATED_PACKAGE_PREFIX,
 			Modifier.PUBLIC | Modifier.FINAL, factoryName, "org.apache.derby.impl.services.reflect.GCInstanceFactory");