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");