This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomee.git
The following commit(s) were added to refs/heads/main by this push:
new d10b9a30a4 TOMEE-4111 - Patch BCEL, which is shaded in servicemix.bcel
(a compile-time dependency of yoko) with a fix to prevent exceeding the maximum
constant pool size (CVE-2022-42920)
d10b9a30a4 is described below
commit d10b9a30a471180eeb053e62c99d70e9f659e6d7
Author: Richard Zowalla <[email protected]>
AuthorDate: Sun Nov 27 13:15:48 2022 +0100
TOMEE-4111 - Patch BCEL, which is shaded in servicemix.bcel (a compile-time
dependency of yoko) with a fix to prevent exceeding the maximum constant pool
size (CVE-2022-42920)
---
deps/pom.xml | 1 +
deps/servicemix-bcel-shade/pom.xml | 100 +++
.../org/apache/bcel/classfile/ConstantPool.java | 378 ++++++++++
.../org/apache/bcel/generic/ConstantPoolGen.java | 794 +++++++++++++++++++++
server/openejb-client/pom.xml | 17 +
5 files changed, 1290 insertions(+)
diff --git a/deps/pom.xml b/deps/pom.xml
index ba8ed469ae..a227676f79 100644
--- a/deps/pom.xml
+++ b/deps/pom.xml
@@ -38,6 +38,7 @@
<module>activemq-ra-shade</module>
<module>commons-dbcp2-shade</module>
<module>commons-fileupload-shade</module>
+ <module>servicemix-bcel-shade</module>
</modules>
<build>
<plugins>
diff --git a/deps/servicemix-bcel-shade/pom.xml
b/deps/servicemix-bcel-shade/pom.xml
new file mode 100644
index 0000000000..5a79b41a29
--- /dev/null
+++ b/deps/servicemix-bcel-shade/pom.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>deps</artifactId>
+ <groupId>org.apache.tomee</groupId>
+ <version>9.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.tomee</groupId>
+ <artifactId>servicemix-bcel-shade</artifactId>
+
+ <name>TomEE :: Deps :: Servicemix Bcel Shade</name>
+
+ <dependencies>
+ <!-- This is required by Yoko -->
+ <dependency>
+ <groupId>org.apache.servicemix.bundles</groupId>
+ <artifactId>org.apache.servicemix.bundles.bcel</artifactId>
+ <version>5.2_2</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.3</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <createSourcesJar>true</createSourcesJar>
+ <useBaseVersion>true</useBaseVersion>
+
<createDependencyReducedPom>false</createDependencyReducedPom>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.tomee.patch</groupId>
+ <artifactId>tomee-patch-plugin</artifactId>
+ <configuration>
+ <select>servicemix-bcel-shade-.*\.jar</select>
+ <transformSources>false</transformSources>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <phase>package</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>rat</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git
a/deps/servicemix-bcel-shade/src/patch/java/org/apache/bcel/classfile/ConstantPool.java
b/deps/servicemix-bcel-shade/src/patch/java/org/apache/bcel/classfile/ConstantPool.java
new file mode 100755
index 0000000000..283ecf55b0
--- /dev/null
+++
b/deps/servicemix-bcel-shade/src/patch/java/org/apache/bcel/classfile/ConstantPool.java
@@ -0,0 +1,378 @@
+package org.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact [email protected].
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.apache.bcel.Constants;
+import org.apache.bcel.generic.ConstantPoolGen;
+import java.io.*;
+
+/**
+ * This class represents the constant pool, i.e., a table of constants.
+ * It may contain null references, due to the JVM specification that skips
+ * an entry after an 8-byte constant (double, long) entry.
+ *
+ * @version $Id$
+ * @see Constant
+ * @author <A HREF="mailto:[email protected]">M. Dahm</A>
+ */
+public class ConstantPool implements Cloneable, Node {
+ private int constant_pool_count;
+ private Constant[] constant_pool;
+
+ /**
+ * @param constant_pool Array of constants
+ */
+ public ConstantPool(Constant[] constant_pool)
+ {
+ setConstantPool(constant_pool);
+ }
+
+ /**
+ * Read constants from given file stream.
+ *
+ * @param file Input stream
+ * @throw IOException
+ * @throw ClassFormatError
+ */
+ ConstantPool(DataInputStream file) throws IOException, ClassFormatError
+ {
+ byte tag;
+
+ constant_pool_count = file.readUnsignedShort();
+ constant_pool = new Constant[constant_pool_count];
+
+ /* constant_pool[0] is unused by the compiler and may be used freely
+ * by the implementation.
+ */
+ for(int i=1; i < constant_pool_count; i++) {
+ constant_pool[i] = Constant.readConstant(file);
+
+ /* Quote from the JVM specification:
+ * "All eight byte constants take up two spots in the constant
pool.
+ * If this is the n'th byte in the constant pool, then the next
item
+ * will be numbered n+2"
+ *
+ * Thus we have to increment the index counter.
+ */
+ tag = constant_pool[i].getTag();
+ if((tag == Constants.CONSTANT_Double) || (tag ==
Constants.CONSTANT_Long))
+ i++;
+ }
+ }
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ public void accept(Visitor v) {
+ v.visitConstantPool(this);
+ }
+
+ /**
+ * Resolve constant to a string representation.
+ *
+ * @param constant Constant to be printed
+ * @return String representation
+ */
+ public String constantToString(Constant c)
+ throws ClassFormatError
+ {
+ String str;
+ int i;
+ byte tag = c.getTag();
+
+ switch(tag) {
+ case Constants.CONSTANT_Class:
+ i = ((ConstantClass)c).getNameIndex();
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ str = Utility.compactClassName(((ConstantUtf8)c).getBytes(),
false);
+ break;
+
+ case Constants.CONSTANT_String:
+ i = ((ConstantString)c).getStringIndex();
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ str = "\"" + escape(((ConstantUtf8)c).getBytes()) + "\"";
+ break;
+
+ case Constants.CONSTANT_Utf8: str =
((ConstantUtf8)c).getBytes(); break;
+ case Constants.CONSTANT_Double: str = "" +
((ConstantDouble)c).getBytes(); break;
+ case Constants.CONSTANT_Float: str = "" +
((ConstantFloat)c).getBytes(); break;
+ case Constants.CONSTANT_Long: str = "" +
((ConstantLong)c).getBytes(); break;
+ case Constants.CONSTANT_Integer: str = "" +
((ConstantInteger)c).getBytes(); break;
+
+ case Constants.CONSTANT_NameAndType:
+ str =
(constantToString(((ConstantNameAndType)c).getNameIndex(),
+ Constants.CONSTANT_Utf8) + " " +
+
constantToString(((ConstantNameAndType)c).getSignatureIndex(),
+ Constants.CONSTANT_Utf8));
+ break;
+
+ case Constants.CONSTANT_InterfaceMethodref: case
Constants.CONSTANT_Methodref:
+ case Constants.CONSTANT_Fieldref:
+ str = (constantToString(((ConstantCP)c).getClassIndex(),
+ Constants.CONSTANT_Class) + "." +
+ constantToString(((ConstantCP)c).getNameAndTypeIndex(),
+ Constants.CONSTANT_NameAndType));
+ break;
+
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " + tag);
+ }
+
+ return str;
+ }
+
+ private static final String escape(String str) {
+ int len = str.length();
+ StringBuffer buf = new StringBuffer(len + 5);
+ char[] ch = str.toCharArray();
+
+ for(int i=0; i < len; i++) {
+ switch(ch[i]) {
+ case '\n' : buf.append("\\n"); break;
+ case '\r' : buf.append("\\r"); break;
+ case '\t' : buf.append("\\t"); break;
+ case '\b' : buf.append("\\b"); break;
+ case '"' : buf.append("\\\""); break;
+ default: buf.append(ch[i]);
+ }
+ }
+
+ return buf.toString();
+ }
+
+
+ /**
+ * Retrieve constant at `index' from constant pool and resolve it to
+ * a string representation.
+ *
+ * @param index of constant in constant pool
+ * @param tag expected type
+ * @return String representation
+ */
+ public String constantToString(int index, byte tag)
+ throws ClassFormatError
+ {
+ Constant c = getConstant(index, tag);
+ return constantToString(c);
+ }
+
+ /**
+ * Dump constant pool to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throw IOException
+ */
+ public void dump(DataOutputStream file) throws IOException
+ {
+ /*
+ * Constants over the size of the constant pool shall not be written
out.
+ * This is a redundant measure as the ConstantPoolGen should have
already
+ * reported an error back in the situation.
+ */
+ int size = constant_pool_count < ConstantPoolGen.CONSTANT_POOL_SIZE -
1 ?
+ constant_pool_count : ConstantPoolGen.CONSTANT_POOL_SIZE -
1;
+
+ file.writeShort(size);
+
+ for(int i=1; i < size; i++)
+ if(constant_pool[i] != null)
+ constant_pool[i].dump(file);
+ }
+
+ /**
+ * Get constant from constant pool.
+ *
+ * @param index Index in constant pool
+ * @return Constant value
+ * @see Constant
+ */
+ public Constant getConstant(int index) {
+ if (index >= constant_pool.length || index < 0)
+ throw new ClassFormatError("Invalid constant pool reference: " +
+ index + ". Constant pool size is: " +
+ constant_pool.length);
+ return constant_pool[index];
+ }
+
+ /**
+ * Get constant from constant pool and check whether it has the
+ * expected type.
+ *
+ * @param index Index in constant pool
+ * @param tag Tag of expected constant, i.e., its type
+ * @return Constant value
+ * @see Constant
+ * @throw ClassFormatError
+ */
+ public Constant getConstant(int index, byte tag)
+ throws ClassFormatError
+ {
+ Constant c;
+
+ c = getConstant(index);
+
+ if(c == null)
+ throw new ClassFormatError("Constant pool at index " + index + "
is null.");
+
+ if(c.getTag() == tag)
+ return c;
+ else
+ throw new ClassFormatError("Expected class `" +
Constants.CONSTANT_NAMES[tag] +
+ "' at index " + index + " and got " + c);
+ }
+
+ /**
+ * @return Array of constants.
+ * @see Constant
+ */
+ public Constant[] getConstantPool() { return constant_pool; }
+ /**
+ * Get string from constant pool and bypass the indirection of
+ * `ConstantClass' and `ConstantString' objects. I.e. these classes have
+ * an index field that points to another entry of the constant pool of
+ * type `ConstantUtf8' which contains the real data.
+ *
+ * @param index Index in constant pool
+ * @param tag Tag of expected constant, either ConstantClass or
ConstantString
+ * @return Contents of string reference
+ * @see ConstantClass
+ * @see ConstantString
+ * @throw ClassFormatError
+ */
+ public String getConstantString(int index, byte tag)
+ throws ClassFormatError
+ {
+ Constant c;
+ int i;
+ String s;
+
+ c = getConstant(index, tag);
+
+ /* This switch() is not that elegant, since the two classes have the
+ * same contents, they just differ in the name of the index
+ * field variable.
+ * But we want to stick to the JVM naming conventions closely though
+ * we could have solved these more elegantly by using the same
+ * variable name or by subclassing.
+ */
+ switch(tag) {
+ case Constants.CONSTANT_Class: i =
((ConstantClass)c).getNameIndex(); break;
+ case Constants.CONSTANT_String: i =
((ConstantString)c).getStringIndex(); break;
+ default:
+ throw new RuntimeException("getConstantString called with
illegal tag " + tag);
+ }
+
+ // Finally get the string from the constant pool
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ return ((ConstantUtf8)c).getBytes();
+ }
+ /**
+ * @return Length of constant pool.
+ */
+ public int getLength()
+ {
+ return constant_pool_count;
+ }
+
+ /**
+ * @param constant Constant to set
+ */
+ public void setConstant(int index, Constant constant) {
+ constant_pool[index] = constant;
+ }
+
+ /**
+ * @param constant_pool
+ */
+ public void setConstantPool(Constant[] constant_pool) {
+ this.constant_pool = constant_pool;
+ constant_pool_count = (constant_pool == null)? 0 :
constant_pool.length;
+ }
+ /**
+ * @return String representation.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for(int i=1; i < constant_pool_count; i++)
+ buf.append(i + ")" + constant_pool[i] + "\n");
+
+ return buf.toString();
+ }
+
+ /**
+ * @return deep copy of this constant pool
+ */
+ public ConstantPool copy() {
+ ConstantPool c = null;
+
+ try {
+ c = (ConstantPool)clone();
+ } catch(CloneNotSupportedException e) {}
+
+ c.constant_pool = new Constant[constant_pool_count];
+
+ for(int i=1; i < constant_pool_count; i++) {
+ if(constant_pool[i] != null)
+ c.constant_pool[i] = constant_pool[i].copy();
+ }
+
+ return c;
+ }
+}
diff --git
a/deps/servicemix-bcel-shade/src/patch/java/org/apache/bcel/generic/ConstantPoolGen.java
b/deps/servicemix-bcel-shade/src/patch/java/org/apache/bcel/generic/ConstantPoolGen.java
new file mode 100755
index 0000000000..b836a124df
--- /dev/null
+++
b/deps/servicemix-bcel-shade/src/patch/java/org/apache/bcel/generic/ConstantPoolGen.java
@@ -0,0 +1,794 @@
+package org.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact [email protected].
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.*;
+import java.util.HashMap;
+
+/**
+ * This class is used to build up a constant pool. The user adds
+ * constants via `addXXX' methods, `addString', `addClass',
+ * etc.. These methods return an index into the constant
+ * pool. Finally, `getFinalConstantPool()' returns the constant pool
+ * built up. Intermediate versions of the constant pool can be
+ * obtained with `getConstantPool()'. A constant pool has capacity for
+ * Constants.MAX_SHORT entries. Note that the first (0) is used by the
+ * JVM and that Double and Long constants need two slots.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:[email protected]">M. Dahm</A>
+ * @see Constant
+ */
+public class ConstantPoolGen {
+ public static final int CONSTANT_POOL_SIZE = 65536;
+ private static final int DEFAULT_BUFFER_SIZE = 256;
+ protected int size = 1024; // Inital size, sufficient in most
cases
+ protected Constant[] constants = new Constant[size];
+ protected int index = 1; // First entry (0) used by JVM
+
+ private static final String METHODREF_DELIM = ":";
+ private static final String IMETHODREF_DELIM = "#";
+ private static final String FIELDREF_DELIM = "&";
+ private static final String NAT_DELIM = "%";
+
+ private static class Index {
+ int index;
+ Index(int i) { index = i; }
+ }
+
+ /**
+ * Initialize with given array of constants.
+ *
+ * @param c array of given constants, new ones will be appended
+ */
+ public ConstantPoolGen(Constant[] cs) {
+ size = Math.min(Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64),
CONSTANT_POOL_SIZE);
+ constants = new Constant[size];
+
+ System.arraycopy(cs, 0, constants, 0, cs.length);
+
+ if(cs.length > 0)
+ index = cs.length;
+
+ for(int i=1; i < index; i++) {
+ Constant c = constants[i];
+
+ if(c instanceof ConstantString) {
+ ConstantString s = (ConstantString)c;
+ ConstantUtf8 u8 =
(ConstantUtf8)constants[s.getStringIndex()];
+
+ string_table.put(u8.getBytes(), new Index(i));
+ } else if(c instanceof ConstantClass) {
+ ConstantClass s = (ConstantClass)c;
+ ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
+
+ class_table.put(u8.getBytes(), new Index(i));
+ } else if(c instanceof ConstantNameAndType) {
+ ConstantNameAndType n = (ConstantNameAndType)c;
+ ConstantUtf8 u8 =
(ConstantUtf8)constants[n.getNameIndex()];
+ ConstantUtf8 u8_2 =
(ConstantUtf8)constants[n.getSignatureIndex()];
+
+ n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(),
new Index(i));
+ } else if(c instanceof ConstantUtf8) {
+ ConstantUtf8 u = (ConstantUtf8)c;
+
+ utf8_table.put(u.getBytes(), new Index(i));
+ } else if(c instanceof ConstantCP) {
+ ConstantCP m = (ConstantCP)c;
+ ConstantClass clazz =
(ConstantClass)constants[m.getClassIndex()];
+ ConstantNameAndType n =
(ConstantNameAndType)constants[m.getNameAndTypeIndex()];
+
+ ConstantUtf8 u8 =
(ConstantUtf8)constants[clazz.getNameIndex()];
+ String class_name = u8.getBytes().replace('/', '.');
+
+ u8 = (ConstantUtf8)constants[n.getNameIndex()];
+ String method_name = u8.getBytes();
+
+ u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
+ String signature = u8.getBytes();
+
+ String delim = METHODREF_DELIM;
+
+ if(c instanceof ConstantInterfaceMethodref)
+ delim = IMETHODREF_DELIM;
+ else if(c instanceof ConstantFieldref)
+ delim = FIELDREF_DELIM;
+
+ cp_table.put(class_name + delim + method_name + delim +
signature, new Index(i));
+ }
+ }
+ }
+
+ /**
+ * Initialize with given constant pool.
+ */
+ public ConstantPoolGen(ConstantPool cp) {
+ this(cp.getConstantPool());
+ }
+
+ /**
+ * Create empty constant pool.
+ */
+ public ConstantPoolGen() {}
+
+ /** Resize internal array of constants.
+ */
+ protected void adjustSize() {
+ // 3 extra spaces are needed as some entries may take 3 slots
+ if (index + 3 >= CONSTANT_POOL_SIZE) {
+ throw new RuntimeException("The number of constants " + (index + 3)
+ + " is over the size of the constant pool: "
+ + (CONSTANT_POOL_SIZE - 1));
+ }
+
+
+ if(index + 3 >= size) {
+ Constant[] cs = constants;
+
+ size *= 2;
+
+ // the constant array shall not exceed the size of the constant
pool
+ size = Math.min(size, CONSTANT_POOL_SIZE);
+
+ constants = new Constant[size];
+ System.arraycopy(cs, 0, constants, 0, index);
+ }
+ }
+
+ private HashMap string_table = new HashMap();
+
+ /**
+ * Look for ConstantString in ConstantPool containing String `str'.
+ *
+ * @param str String to search for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupString(String str) {
+ Index index = (Index)string_table.get(str);
+ return (index != null)? index.index : -1;
+ }
+
+ /**
+ * Add a new String constant to the ConstantPool, if it is not already in
there.
+ *
+ * @param str String to add
+ * @return index of entry
+ */
+ public int addString(String str) {
+ int ret;
+
+ if((ret = lookupString(str)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ConstantUtf8 u8 = new ConstantUtf8(str);
+ ConstantString s = new ConstantString(index);
+
+ constants[index++] = u8;
+ ret = index;
+ constants[index++] = s;
+
+ string_table.put(str, new Index(ret));
+
+ return ret;
+ }
+
+ private HashMap class_table = new HashMap();
+
+ /**
+ * Look for ConstantClass in ConstantPool named `str'.
+ *
+ * @param str String to search for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupClass(String str) {
+ Index index = (Index)class_table.get(str.replace('.', '/'));
+ return (index != null)? index.index : -1;
+ }
+
+ private int addClass_(String clazz) {
+ int ret;
+
+ if((ret = lookupClass(clazz)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ConstantClass c = new ConstantClass(addUtf8(clazz));
+
+ ret = index;
+ constants[index++] = c;
+
+ class_table.put(clazz, new Index(ret));
+
+ return ret;
+ }
+
+ /**
+ * Add a new Class reference to the ConstantPool, if it is not already in
there.
+ *
+ * @param str Class to add
+ * @return index of entry
+ */
+ public int addClass(String str) {
+ return addClass_(str.replace('.', '/'));
+ }
+
+ /**
+ * Add a new Class reference to the ConstantPool for a given type.
+ *
+ * @param str Class to add
+ * @return index of entry
+ */
+ public int addClass(ObjectType type) {
+ return addClass(type.getClassName());
+ }
+
+ /**
+ * Add a reference to an array class (e.g. String[][]) as needed by
MULTIANEWARRAY
+ * instruction, e.g. to the ConstantPool.
+ *
+ * @param type type of array class
+ * @return index of entry
+ */
+ public int addArrayClass(ArrayType type) {
+ return addClass_(type.getSignature());
+ }
+
+ /**
+ * Look for ConstantInteger in ConstantPool.
+ *
+ * @param n integer number to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupInteger(int n) {
+ for(int i=1; i < index; i++) {
+ if(constants[i] instanceof ConstantInteger) {
+ ConstantInteger c = (ConstantInteger)constants[i];
+
+ if(c.getBytes() == n)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Add a new Integer constant to the ConstantPool, if it is not already in
there.
+ *
+ * @param n integer number to add
+ * @return index of entry
+ */
+ public int addInteger(int n) {
+ int ret;
+
+ if((ret = lookupInteger(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index++] = new ConstantInteger(n);
+
+ return ret;
+ }
+
+ /**
+ * Look for ConstantFloat in ConstantPool.
+ *
+ * @param n Float number to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupFloat(float n) {
+ for(int i=1; i < index; i++) {
+ if(constants[i] instanceof ConstantFloat) {
+ ConstantFloat c = (ConstantFloat)constants[i];
+
+ if(c.getBytes() == n)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Add a new Float constant to the ConstantPool, if it is not already in
there.
+ *
+ * @param n Float number to add
+ * @return index of entry
+ */
+ public int addFloat(float n) {
+ int ret;
+
+ if((ret = lookupFloat(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index++] = new ConstantFloat(n);
+
+ return ret;
+ }
+
+ private HashMap utf8_table = new HashMap();
+
+ /**
+ * Look for ConstantUtf8 in ConstantPool.
+ *
+ * @param n Utf8 string to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupUtf8(String n) {
+ Index index = (Index)utf8_table.get(n);
+
+ return (index != null)? index.index : -1;
+ }
+
+ /**
+ * Add a new Utf8 constant to the ConstantPool, if it is not already in
there.
+ *
+ * @param n Utf8 string to add
+ * @return index of entry
+ */
+ public int addUtf8(String n) {
+ int ret;
+
+ if((ret = lookupUtf8(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index++] = new ConstantUtf8(n);
+
+ utf8_table.put(n, new Index(ret));
+
+ return ret;
+ }
+
+ /**
+ * Look for ConstantLong in ConstantPool.
+ *
+ * @param n Long number to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupLong(long n) {
+ for(int i=1; i < index; i++) {
+ if(constants[i] instanceof ConstantLong) {
+ ConstantLong c = (ConstantLong)constants[i];
+
+ if(c.getBytes() == n)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Add a new long constant to the ConstantPool, if it is not already in
there.
+ *
+ * @param n Long number to add
+ * @return index of entry
+ */
+ public int addLong(long n) {
+ int ret;
+
+ if((ret = lookupLong(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index] = new ConstantLong(n);
+ index += 2; // Wastes one entry according to spec
+
+ return ret;
+ }
+
+ /**
+ * Look for ConstantDouble in ConstantPool.
+ *
+ * @param n Double number to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupDouble(double n) {
+ for(int i=1; i < index; i++) {
+ if(constants[i] instanceof ConstantDouble) {
+ ConstantDouble c = (ConstantDouble)constants[i];
+
+ if(c.getBytes() == n)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Add a new double constant to the ConstantPool, if it is not already in
there.
+ *
+ * @param n Double number to add
+ * @return index of entry
+ */
+ public int addDouble(double n) {
+ int ret;
+
+ if((ret = lookupDouble(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index] = new ConstantDouble(n);
+ index += 2; // Wastes one entry according to spec
+
+ return ret;
+ }
+
+ private HashMap n_a_t_table = new HashMap();
+
+ /**
+ * Look for ConstantNameAndType in ConstantPool.
+ *
+ * @param name of variable/method
+ * @param signature of variable/method
+ * @return index on success, -1 otherwise
+ */
+ public int lookupNameAndType(String name, String signature) {
+ Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature);
+ return (index != null)? index.index : -1;
+ }
+
+ /**
+ * Add a new NameAndType constant to the ConstantPool if it is not already
+ * in there.
+ *
+ * @param n NameAndType string to add
+ * @return index of entry
+ */
+ public int addNameAndType(String name, String signature) {
+ int ret;
+ int name_index, signature_index;
+
+ if((ret = lookupNameAndType(name, signature)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ name_index = addUtf8(name);
+ signature_index = addUtf8(signature);
+ ret = index;
+ constants[index++] = new ConstantNameAndType(name_index,
signature_index);
+
+ n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret));
+ return ret;
+ }
+
+ private HashMap cp_table = new HashMap();
+
+ /**
+ * Look for ConstantMethodref in ConstantPool.
+ *
+ * @param class_name Where to find method
+ * @param method_name Guess what
+ * @param signature return and argument types
+ * @return index on success, -1 otherwise
+ */
+ public int lookupMethodref(String class_name, String method_name, String
signature) {
+ Index index = (Index)cp_table.get(class_name + METHODREF_DELIM +
method_name +
+ METHODREF_DELIM + signature);
+ return (index != null)? index.index : -1;
+ }
+
+ public int lookupMethodref(MethodGen method) {
+ return lookupMethodref(method.getClassName(), method.getName(),
+ method.getSignature());
+ }
+
+ /**
+ * Add a new Methodref constant to the ConstantPool, if it is not already
+ * in there.
+ *
+ * @param n Methodref string to add
+ * @return index of entry
+ */
+ public int addMethodref(String class_name, String method_name, String
signature) {
+ int ret, class_index, name_and_type_index;
+
+ if((ret = lookupMethodref(class_name, method_name, signature)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ name_and_type_index = addNameAndType(method_name, signature);
+ class_index = addClass(class_name);
+ ret = index;
+ constants[index++] = new ConstantMethodref(class_index,
name_and_type_index);
+
+ cp_table.put(class_name + METHODREF_DELIM + method_name +
+ METHODREF_DELIM + signature, new Index(ret));
+
+ return ret;
+ }
+
+ public int addMethodref(MethodGen method) {
+ return addMethodref(method.getClassName(), method.getName(),
+ method.getSignature());
+ }
+
+ /**
+ * Look for ConstantInterfaceMethodref in ConstantPool.
+ *
+ * @param class_name Where to find method
+ * @param method_name Guess what
+ * @param signature return and argument types
+ * @return index on success, -1 otherwise
+ */
+ public int lookupInterfaceMethodref(String class_name, String method_name,
String signature) {
+ Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM +
method_name +
+ IMETHODREF_DELIM + signature);
+ return (index != null)? index.index : -1;
+ }
+
+ public int lookupInterfaceMethodref(MethodGen method) {
+ return lookupInterfaceMethodref(method.getClassName(),
method.getName(),
+ method.getSignature());
+ }
+
+ /**
+ * Add a new InterfaceMethodref constant to the ConstantPool, if it is not
already
+ * in there.
+ *
+ * @param n InterfaceMethodref string to add
+ * @return index of entry
+ */
+ public int addInterfaceMethodref(String class_name, String method_name,
String signature) {
+ int ret, class_index, name_and_type_index;
+
+ if((ret = lookupInterfaceMethodref(class_name, method_name,
signature)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ class_index = addClass(class_name);
+ name_and_type_index = addNameAndType(method_name, signature);
+ ret = index;
+ constants[index++] = new ConstantInterfaceMethodref(class_index,
name_and_type_index);
+
+ cp_table.put(class_name + IMETHODREF_DELIM + method_name +
+ IMETHODREF_DELIM + signature, new Index(ret));
+
+ return ret;
+ }
+
+ public int addInterfaceMethodref(MethodGen method) {
+ return addInterfaceMethodref(method.getClassName(), method.getName(),
+ method.getSignature());
+ }
+
+ /**
+ * Look for ConstantFieldref in ConstantPool.
+ *
+ * @param class_name Where to find method
+ * @param field_name Guess what
+ * @param signature return and argument types
+ * @return index on success, -1 otherwise
+ */
+ public int lookupFieldref(String class_name, String field_name, String
signature) {
+ Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM +
field_name +
+ FIELDREF_DELIM + signature);
+ return (index != null)? index.index : -1;
+ }
+
+ /**
+ * Add a new Fieldref constant to the ConstantPool, if it is not already
+ * in there.
+ *
+ * @param n Fieldref string to add
+ * @return index of entry
+ */
+ public int addFieldref(String class_name, String field_name, String
signature) {
+ int ret;
+ int class_index, name_and_type_index;
+
+ if((ret = lookupFieldref(class_name, field_name, signature)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ class_index = addClass(class_name);
+ name_and_type_index = addNameAndType(field_name, signature);
+ ret = index;
+ constants[index++] = new ConstantFieldref(class_index,
name_and_type_index);
+
+ cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM
+ signature, new Index(ret));
+
+ return ret;
+ }
+
+ /**
+ * @param i index in constant pool
+ * @return constant pool entry at index i
+ */
+ public Constant getConstant(int i) { return constants[i]; }
+
+ /**
+ * Use with care!
+ *
+ * @param i index in constant pool
+ * @param c new constant pool entry at index i
+ */
+ public void setConstant(int i, Constant c) { constants[i] = c; }
+
+ /**
+ * @return intermediate constant pool
+ */
+ public ConstantPool getConstantPool() {
+ return new ConstantPool(constants);
+ }
+
+ /**
+ * @return current size of constant pool
+ */
+ public int getSize() {
+ return index;
+ }
+
+ /**
+ * @return constant pool with proper length
+ */
+ public ConstantPool getFinalConstantPool() {
+ Constant[] cs = new Constant[index];
+
+ System.arraycopy(constants, 0, cs, 0, index);
+
+ return new ConstantPool(cs);
+ }
+
+ /**
+ * @return String representation.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for(int i=1; i < index; i++)
+ buf.append(i + ")" + constants[i] + "\n");
+
+ return buf.toString();
+ }
+
+ /** Import constant from another ConstantPool and return new index.
+ */
+ public int addConstant(Constant c, ConstantPoolGen cp) {
+ Constant[] constants = cp.getConstantPool().getConstantPool();
+
+ switch(c.getTag()) {
+ case Constants.CONSTANT_String: {
+ ConstantString s = (ConstantString)c;
+ ConstantUtf8 u8 =
(ConstantUtf8)constants[s.getStringIndex()];
+
+ return addString(u8.getBytes());
+ }
+
+ case Constants.CONSTANT_Class: {
+ ConstantClass s = (ConstantClass)c;
+ ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
+
+ return addClass(u8.getBytes());
+ }
+
+ case Constants.CONSTANT_NameAndType: {
+ ConstantNameAndType n = (ConstantNameAndType)c;
+ ConstantUtf8 u8 =
(ConstantUtf8)constants[n.getNameIndex()];
+ ConstantUtf8 u8_2 =
(ConstantUtf8)constants[n.getSignatureIndex()];
+
+ return addNameAndType(u8.getBytes(), u8_2.getBytes());
+ }
+
+ case Constants.CONSTANT_Utf8:
+ return addUtf8(((ConstantUtf8)c).getBytes());
+
+ case Constants.CONSTANT_Double:
+ return addDouble(((ConstantDouble)c).getBytes());
+
+ case Constants.CONSTANT_Float:
+ return addFloat(((ConstantFloat)c).getBytes());
+
+ case Constants.CONSTANT_Long:
+ return addLong(((ConstantLong)c).getBytes());
+
+ case Constants.CONSTANT_Integer:
+ return addInteger(((ConstantInteger)c).getBytes());
+
+ case Constants.CONSTANT_InterfaceMethodref: case
Constants.CONSTANT_Methodref:
+ case Constants.CONSTANT_Fieldref: {
+ ConstantCP m = (ConstantCP)c;
+ ConstantClass clazz =
(ConstantClass)constants[m.getClassIndex()];
+ ConstantNameAndType n =
(ConstantNameAndType)constants[m.getNameAndTypeIndex()];
+ ConstantUtf8 u8 =
(ConstantUtf8)constants[clazz.getNameIndex()];
+ String class_name = u8.getBytes().replace('/', '.');
+
+ u8 = (ConstantUtf8)constants[n.getNameIndex()];
+ String name = u8.getBytes();
+
+ u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
+ String signature = u8.getBytes();
+
+ switch(c.getTag()) {
+ case Constants.CONSTANT_InterfaceMethodref:
+ return addInterfaceMethodref(class_name, name,
signature);
+
+ case Constants.CONSTANT_Methodref:
+ return addMethodref(class_name, name, signature);
+
+ case Constants.CONSTANT_Fieldref:
+ return addFieldref(class_name, name, signature);
+
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " +
c);
+ }
+ }
+
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " + c);
+ }
+ }
+}
diff --git a/server/openejb-client/pom.xml b/server/openejb-client/pom.xml
index caa8a77639..2a09646e1a 100644
--- a/server/openejb-client/pom.xml
+++ b/server/openejb-client/pom.xml
@@ -170,6 +170,23 @@
<groupId>org.apache.yoko</groupId>
<artifactId>yoko-rmi-impl</artifactId>
<version>1.4</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.servicemix.bundles</groupId>
+ <artifactId>org.apache.servicemix.bundles.bcel</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomee</groupId>
+ <artifactId>servicemix-bcel-shade</artifactId>
+ <version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.servicemix.bundles</groupId>
+ <artifactId>org.apache.servicemix.bundles.bcel</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
</dependencies>
</project>