init
This commit is contained in:
701
java/org/apache/tomcat/util/Diagnostics.java
Normal file
701
java/org/apache/tomcat/util/Diagnostics.java
Normal file
File diff suppressed because it is too large
Load Diff
71
java/org/apache/tomcat/util/ExceptionUtils.java
Normal file
71
java/org/apache/tomcat/util/ExceptionUtils.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
|
||||
/**
|
||||
* Utilities for handling Throwables and Exceptions.
|
||||
*/
|
||||
public class ExceptionUtils {
|
||||
|
||||
/**
|
||||
* Checks whether the supplied Throwable is one that needs to be
|
||||
* rethrown and swallows all others.
|
||||
* @param t the Throwable to check
|
||||
*/
|
||||
public static void handleThrowable(Throwable t) {
|
||||
if (t instanceof ThreadDeath) {
|
||||
throw (ThreadDeath) t;
|
||||
}
|
||||
if (t instanceof StackOverflowError) {
|
||||
// Swallow silently - it should be recoverable
|
||||
return;
|
||||
}
|
||||
if (t instanceof VirtualMachineError) {
|
||||
throw (VirtualMachineError) t;
|
||||
}
|
||||
// All other instances of Throwable will be silently swallowed
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the supplied Throwable is an instance of
|
||||
* <code>InvocationTargetException</code> and returns the throwable that is
|
||||
* wrapped by it, if there is any.
|
||||
*
|
||||
* @param t the Throwable to check
|
||||
* @return <code>t</code> or <code>t.getCause()</code>
|
||||
*/
|
||||
public static Throwable unwrapInvocationTargetException(Throwable t) {
|
||||
if (t instanceof InvocationTargetException && t.getCause() != null) {
|
||||
return t.getCause();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NO-OP method provided to enable simple pre-loading of this class. Since
|
||||
* the class is used extensively in error handling, it is prudent to
|
||||
* pre-load it to avoid any failure to load this class masking the true
|
||||
* problem during error handling.
|
||||
*/
|
||||
public static void preload() {
|
||||
// NO-OP
|
||||
}
|
||||
}
|
||||
538
java/org/apache/tomcat/util/IntrospectionUtils.java
Normal file
538
java/org/apache/tomcat/util/IntrospectionUtils.java
Normal file
File diff suppressed because it is too large
Load Diff
30
java/org/apache/tomcat/util/LocalStrings.properties
Normal file
30
java/org/apache/tomcat/util/LocalStrings.properties
Normal file
@@ -0,0 +1,30 @@
|
||||
# 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.
|
||||
|
||||
diagnostics.threadDumpTitle=Full thread dump
|
||||
diagnostics.vmInfoClassCompilation=Class compilation
|
||||
diagnostics.vmInfoClassLoading=Class loading
|
||||
diagnostics.vmInfoGarbageCollectors=Garbage Collector [{0}]
|
||||
diagnostics.vmInfoLogger=Logger information
|
||||
diagnostics.vmInfoMemory=Memory information
|
||||
diagnostics.vmInfoMemoryManagers=Memory Manager [{0}]
|
||||
diagnostics.vmInfoMemoryPools=Memory Pool [{0}]
|
||||
diagnostics.vmInfoOs=OS information
|
||||
diagnostics.vmInfoPath=Path information
|
||||
diagnostics.vmInfoRuntime=Runtime information
|
||||
diagnostics.vmInfoStartup=Startup arguments
|
||||
diagnostics.vmInfoSystem=System properties
|
||||
diagnostics.vmInfoThreadCounts=Thread counts
|
||||
diagnostics.vmInfoThreadMxBean=ThreadMXBean capabilities
|
||||
18
java/org/apache/tomcat/util/LocalStrings_de.properties
Normal file
18
java/org/apache/tomcat/util/LocalStrings_de.properties
Normal file
@@ -0,0 +1,18 @@
|
||||
# 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.
|
||||
|
||||
diagnostics.threadDumpTitle=Kompletter Thread Dump
|
||||
diagnostics.vmInfoClassCompilation=Übersetzung der Klasse
|
||||
diagnostics.vmInfoLogger=Logger-Information
|
||||
19
java/org/apache/tomcat/util/LocalStrings_es.properties
Normal file
19
java/org/apache/tomcat/util/LocalStrings_es.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
# 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.
|
||||
|
||||
diagnostics.threadDumpTitle=Volcado del hilo completo
|
||||
diagnostics.vmInfoClassCompilation=Compilación de clase
|
||||
diagnostics.vmInfoLogger=Información de logueo
|
||||
diagnostics.vmInfoSystem=Propiedades del sistema
|
||||
30
java/org/apache/tomcat/util/LocalStrings_fr.properties
Normal file
30
java/org/apache/tomcat/util/LocalStrings_fr.properties
Normal file
@@ -0,0 +1,30 @@
|
||||
# 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.
|
||||
|
||||
diagnostics.threadDumpTitle=Traces complètes des threads
|
||||
diagnostics.vmInfoClassCompilation=Compilation de la classe
|
||||
diagnostics.vmInfoClassLoading=Chargeur de classes
|
||||
diagnostics.vmInfoGarbageCollectors=Garbage Collector [{0}]
|
||||
diagnostics.vmInfoLogger=Information sur le journal
|
||||
diagnostics.vmInfoMemory=Information mémoire
|
||||
diagnostics.vmInfoMemoryManagers=Gestionnaire de mémoire [{0}]
|
||||
diagnostics.vmInfoMemoryPools=Pool de mémoire [{0}]
|
||||
diagnostics.vmInfoOs=Information sur l'OS
|
||||
diagnostics.vmInfoPath=Imformation de chemin
|
||||
diagnostics.vmInfoRuntime=Information sur l'environnement d'exécution
|
||||
diagnostics.vmInfoStartup=Arguments de démarrage
|
||||
diagnostics.vmInfoSystem=Paramètres système
|
||||
diagnostics.vmInfoThreadCounts=Nombre de fils d'exécution (threads)
|
||||
diagnostics.vmInfoThreadMxBean=Capacités de ThreadMXBean
|
||||
30
java/org/apache/tomcat/util/LocalStrings_ja.properties
Normal file
30
java/org/apache/tomcat/util/LocalStrings_ja.properties
Normal file
@@ -0,0 +1,30 @@
|
||||
# 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.
|
||||
|
||||
diagnostics.threadDumpTitle=完全なスレッドダンプ
|
||||
diagnostics.vmInfoClassCompilation=Class コンパイル
|
||||
diagnostics.vmInfoClassLoading=クラスローディング
|
||||
diagnostics.vmInfoGarbageCollectors=ガベージコレクタ [{0}]
|
||||
diagnostics.vmInfoLogger=Logger 情報
|
||||
diagnostics.vmInfoMemory=メモリ情報
|
||||
diagnostics.vmInfoMemoryManagers=メモリマネージャ[{0}]
|
||||
diagnostics.vmInfoMemoryPools=メモリプール [{0}]
|
||||
diagnostics.vmInfoOs=OS情報
|
||||
diagnostics.vmInfoPath=パス情報
|
||||
diagnostics.vmInfoRuntime=Runtime 情報
|
||||
diagnostics.vmInfoStartup=起動引数
|
||||
diagnostics.vmInfoSystem=システムプロパティ
|
||||
diagnostics.vmInfoThreadCounts=スレッドカウント
|
||||
diagnostics.vmInfoThreadMxBean=ThreadMXBeanの機能
|
||||
30
java/org/apache/tomcat/util/LocalStrings_ko.properties
Normal file
30
java/org/apache/tomcat/util/LocalStrings_ko.properties
Normal file
@@ -0,0 +1,30 @@
|
||||
# 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.
|
||||
|
||||
diagnostics.threadDumpTitle=풀 쓰레드 덤프
|
||||
diagnostics.vmInfoClassCompilation=클래스 컴파일
|
||||
diagnostics.vmInfoClassLoading=클래스 로딩
|
||||
diagnostics.vmInfoGarbageCollectors=Garbage Collector [{0}]
|
||||
diagnostics.vmInfoLogger=Logger 정보
|
||||
diagnostics.vmInfoMemory=메모리 정보
|
||||
diagnostics.vmInfoMemoryManagers=메모리 매니저 [{0}]
|
||||
diagnostics.vmInfoMemoryPools=메모리 풀 [{0}]
|
||||
diagnostics.vmInfoOs=운영체제 정보
|
||||
diagnostics.vmInfoPath=경로 정보
|
||||
diagnostics.vmInfoRuntime=런타임 정보
|
||||
diagnostics.vmInfoStartup=프로그램 시작 아규먼트들
|
||||
diagnostics.vmInfoSystem=시스템 프로퍼티들
|
||||
diagnostics.vmInfoThreadCounts=쓰레드 개수
|
||||
diagnostics.vmInfoThreadMxBean=ThreadMXBean 용량정보들
|
||||
16
java/org/apache/tomcat/util/LocalStrings_ru.properties
Normal file
16
java/org/apache/tomcat/util/LocalStrings_ru.properties
Normal file
@@ -0,0 +1,16 @@
|
||||
# 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.
|
||||
|
||||
diagnostics.threadDumpTitle=Сброс полной нити
|
||||
24
java/org/apache/tomcat/util/LocalStrings_zh_CN.properties
Normal file
24
java/org/apache/tomcat/util/LocalStrings_zh_CN.properties
Normal file
@@ -0,0 +1,24 @@
|
||||
# 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.
|
||||
|
||||
diagnostics.threadDumpTitle=打印全部线程
|
||||
diagnostics.vmInfoClassCompilation=:)class汇编
|
||||
diagnostics.vmInfoClassLoading=类加载中
|
||||
diagnostics.vmInfoGarbageCollectors=垃圾收集器[{0}]
|
||||
diagnostics.vmInfoLogger=日志记录器(Logger)信息
|
||||
diagnostics.vmInfoOs=操作系统信息
|
||||
diagnostics.vmInfoRuntime=运行时信息
|
||||
diagnostics.vmInfoSystem=系统.属性
|
||||
diagnostics.vmInfoThreadCounts=线程数
|
||||
99
java/org/apache/tomcat/util/MultiThrowable.java
Normal file
99
java/org/apache/tomcat/util/MultiThrowable.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wraps a list of throwables as a single throwable. This is intended to be used
|
||||
* when multiple actions are taken where each may throw an exception but all
|
||||
* actions are taken before any errors are reported.
|
||||
* <p>
|
||||
* This class is <b>NOT</b> threadsafe.
|
||||
*/
|
||||
public class MultiThrowable extends Throwable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<Throwable> throwables = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Add a throwable to the list of wrapped throwables.
|
||||
*
|
||||
* @param t The throwable to add
|
||||
*/
|
||||
public void add(Throwable t) {
|
||||
throwables.add(t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return A read-only list of the wrapped throwables.
|
||||
*/
|
||||
public List<Throwable> getThrowables() {
|
||||
return Collections.unmodifiableList(throwables);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {@code null} if there are no wrapped throwables, the Throwable if
|
||||
* there is a single wrapped throwable or the current instance of
|
||||
* there are multiple wrapped throwables
|
||||
*/
|
||||
public Throwable getThrowable() {
|
||||
if (size() == 0) {
|
||||
return null;
|
||||
} else if (size() == 1) {
|
||||
return throwables.get(0);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The number of throwables currently wrapped by this instance.
|
||||
*/
|
||||
public int size() {
|
||||
return throwables.size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overrides the default implementation to provide a concatenation of the
|
||||
* messages associated with each of the wrapped throwables. Note that the
|
||||
* format of the returned String is not guaranteed to be fixed and may
|
||||
* change in a future release.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(super.toString());
|
||||
sb.append(": ");
|
||||
sb.append(size());
|
||||
sb.append(" wrapped Throwables: ");
|
||||
for (Throwable t : throwables) {
|
||||
sb.append("[");
|
||||
sb.append(t.getMessage());
|
||||
sb.append("]");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
190
java/org/apache/tomcat/util/bcel/Const.java
Normal file
190
java/org/apache/tomcat/util/bcel/Const.java
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel;
|
||||
|
||||
/**
|
||||
* Constants for the project, mostly defined in the JVM specification.
|
||||
*/
|
||||
public final class Const {
|
||||
|
||||
/** One of the access flags for fields, methods, or classes.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1">
|
||||
* Flag definitions for Classes in the Java Virtual Machine Specification (Java SE 9 Edition).</a>
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.5">
|
||||
* Flag definitions for Fields in the Java Virtual Machine Specification (Java SE 9 Edition).</a>
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.6">
|
||||
* Flag definitions for Methods in the Java Virtual Machine Specification (Java SE 9 Edition).</a>
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.6-300-D.1-D.1">
|
||||
* Flag definitions for Inner Classes in the Java Virtual Machine Specification (Java SE 9 Edition).</a>
|
||||
*/
|
||||
public static final short ACC_FINAL = 0x0010;
|
||||
|
||||
/** One of the access flags for fields, methods, or classes.
|
||||
*/
|
||||
public static final short ACC_INTERFACE = 0x0200;
|
||||
|
||||
/** One of the access flags for fields, methods, or classes.
|
||||
*/
|
||||
public static final short ACC_ABSTRACT = 0x0400;
|
||||
|
||||
/** One of the access flags for fields, methods, or classes.
|
||||
*/
|
||||
public static final short ACC_ANNOTATION = 0x2000;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as type UTF-8.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.7">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Utf8 = 1;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as type Integer.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Integer = 3;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as type Float.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Float = 4;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as type Long.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Long = 5;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as type Double.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Double = 6;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as a Class
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.1">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Class = 7;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as type String
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.3">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_String = 8;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as a Field Reference.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Fieldref = 9;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as a Method Reference.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Methodref = 10;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as an Interface Method Reference.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_InterfaceMethodref = 11;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as a name and type.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.6">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_NameAndType = 12;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as a Method Handle.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.8">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_MethodHandle = 15;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as a Method Type.
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.9">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_MethodType = 16;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as dynamically computed.
|
||||
* @see <a href="https://bugs.openjdk.java.net/secure/attachment/74618/constant-dynamic.html">
|
||||
* Change request for JEP 309</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Dynamic = 17;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as an Invoke Dynamic
|
||||
* @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10">
|
||||
* The Constant Pool in The Java Virtual Machine Specification</a>
|
||||
*/
|
||||
public static final byte CONSTANT_InvokeDynamic = 18;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as a Module Reference.
|
||||
*
|
||||
* <p>Note: Early access Java 9 support- currently subject to change</p>
|
||||
*
|
||||
* @see <a href="http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html#jigsaw-2.6">
|
||||
* JPMS: Modules in the Java Language and JVM</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Module = 19;
|
||||
|
||||
/**
|
||||
* Marks a constant pool entry as a Package Reference.
|
||||
*
|
||||
* <p>Note: Early access Java 9 support- currently subject to change</p>
|
||||
*
|
||||
* @see <a href="http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html#jigsaw-2.6">
|
||||
* JPMS: Modules in the Java Language and JVM</a>
|
||||
*/
|
||||
public static final byte CONSTANT_Package = 20;
|
||||
|
||||
/**
|
||||
* The names of the types of entries in a constant pool.
|
||||
* Use getConstantName instead
|
||||
*/
|
||||
private static final String[] CONSTANT_NAMES = {
|
||||
"", "CONSTANT_Utf8", "", "CONSTANT_Integer",
|
||||
"CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double",
|
||||
"CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref",
|
||||
"CONSTANT_Methodref", "CONSTANT_InterfaceMethodref",
|
||||
"CONSTANT_NameAndType", "", "", "CONSTANT_MethodHandle",
|
||||
"CONSTANT_MethodType", "CONSTANT_Dynamic", "CONSTANT_InvokeDynamic",
|
||||
"CONSTANT_Module", "CONSTANT_Package"};
|
||||
|
||||
public static String getConstantName(int index) {
|
||||
return CONSTANT_NAMES[index];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
public class AnnotationElementValue extends ElementValue
|
||||
{
|
||||
// For annotation element values, this is the annotation
|
||||
private final AnnotationEntry annotationEntry;
|
||||
|
||||
AnnotationElementValue(final int type, final AnnotationEntry annotationEntry,
|
||||
final ConstantPool cpool)
|
||||
{
|
||||
super(type, cpool);
|
||||
if (type != ANNOTATION) {
|
||||
throw new RuntimeException(
|
||||
"Only element values of type annotation can be built with this ctor - type specified: " + type);
|
||||
}
|
||||
this.annotationEntry = annotationEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringifyValue()
|
||||
{
|
||||
return annotationEntry.toString();
|
||||
}
|
||||
|
||||
public AnnotationEntry getAnnotationEntry()
|
||||
{
|
||||
return annotationEntry;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* represents one annotation in the annotation table
|
||||
*/
|
||||
public class AnnotationEntry {
|
||||
|
||||
private final int type_index;
|
||||
private final ConstantPool constant_pool;
|
||||
|
||||
private final List<ElementValuePair> element_value_pairs;
|
||||
|
||||
/*
|
||||
* Creates an AnnotationEntry from a DataInputStream
|
||||
*
|
||||
* @param input
|
||||
* @param constant_pool
|
||||
* @throws IOException
|
||||
*/
|
||||
AnnotationEntry(final DataInput input, final ConstantPool constant_pool) throws IOException {
|
||||
|
||||
this.constant_pool = constant_pool;
|
||||
|
||||
type_index = input.readUnsignedShort();
|
||||
final int num_element_value_pairs = input.readUnsignedShort();
|
||||
|
||||
element_value_pairs = new ArrayList<>(num_element_value_pairs);
|
||||
for (int i = 0; i < num_element_value_pairs; i++) {
|
||||
element_value_pairs.add(new ElementValuePair(input, constant_pool));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the annotation type name
|
||||
*/
|
||||
public String getAnnotationType() {
|
||||
final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(type_index, Const.CONSTANT_Utf8);
|
||||
return c.getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the element value pairs in this annotation entry
|
||||
*/
|
||||
public List<ElementValuePair> getElementValuePairs() {
|
||||
return element_value_pairs;
|
||||
}
|
||||
}
|
||||
49
java/org/apache/tomcat/util/bcel/classfile/Annotations.java
Normal file
49
java/org/apache/tomcat/util/bcel/classfile/Annotations.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* base class for annotations
|
||||
*/
|
||||
public class Annotations {
|
||||
|
||||
private final AnnotationEntry[] annotation_table;
|
||||
|
||||
/**
|
||||
* @param input Input stream
|
||||
* @param constant_pool Array of constants
|
||||
*/
|
||||
Annotations(final DataInput input, final ConstantPool constant_pool) throws IOException {
|
||||
final int annotation_table_length = input.readUnsignedShort();
|
||||
annotation_table = new AnnotationEntry[annotation_table_length];
|
||||
for (int i = 0; i < annotation_table_length; i++) {
|
||||
annotation_table[i] = new AnnotationEntry(input, constant_pool);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the array of annotation entries in this annotation
|
||||
*/
|
||||
public AnnotationEntry[] getAnnotationEntries() {
|
||||
return annotation_table;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
public class ArrayElementValue extends ElementValue
|
||||
{
|
||||
// For array types, this is the array
|
||||
private final ElementValue[] evalues;
|
||||
|
||||
ArrayElementValue(final int type, final ElementValue[] datums, final ConstantPool cpool)
|
||||
{
|
||||
super(type, cpool);
|
||||
if (type != ARRAY) {
|
||||
throw new RuntimeException(
|
||||
"Only element values of type array can be built with this ctor - type specified: " + type);
|
||||
}
|
||||
this.evalues = datums;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringifyValue()
|
||||
{
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
for (int i = 0; i < evalues.length; i++)
|
||||
{
|
||||
sb.append(evalues[i].stringifyValue());
|
||||
if ((i + 1) < evalues.length) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public ElementValue[] getElementValuesArray()
|
||||
{
|
||||
return evalues;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
public class ClassElementValue extends ElementValue
|
||||
{
|
||||
// For primitive types and string type, this points to the value entry in
|
||||
// the cpool
|
||||
// For 'class' this points to the class entry in the cpool
|
||||
private final int idx;
|
||||
|
||||
ClassElementValue(final int type, final int idx, final ConstantPool cpool) {
|
||||
super(type, cpool);
|
||||
this.idx = idx;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String stringifyValue()
|
||||
{
|
||||
final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(idx,
|
||||
Const.CONSTANT_Utf8);
|
||||
return cu8.getBytes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
/**
|
||||
* Thrown when the BCEL attempts to read a class file and determines
|
||||
* that the file is malformed or otherwise cannot be interpreted as a
|
||||
* class file.
|
||||
*/
|
||||
public class ClassFormatException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 3243149520175287759L;
|
||||
|
||||
public ClassFormatException() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public ClassFormatException(final String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
247
java/org/apache/tomcat/util/bcel/classfile/ClassParser.java
Normal file
247
java/org/apache/tomcat/util/bcel/classfile/ClassParser.java
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* Wrapper class that parses a given Java .class file. The method <A
|
||||
* href ="#parse">parse</A> returns a <A href ="JavaClass.html">
|
||||
* JavaClass</A> object on success. When an I/O error or an
|
||||
* inconsistency occurs an appropriate exception is propagated back to
|
||||
* the caller.
|
||||
*
|
||||
* The structure and the names comply, except for a few conveniences,
|
||||
* exactly with the <A href="http://docs.oracle.com/javase/specs/">
|
||||
* JVM specification 1.0</a>. See this paper for
|
||||
* further details about the structure of a bytecode file.
|
||||
*/
|
||||
public final class ClassParser {
|
||||
|
||||
private static final int MAGIC = 0xCAFEBABE;
|
||||
|
||||
private final DataInput dataInputStream;
|
||||
private String class_name, superclass_name;
|
||||
private int access_flags; // Access rights of parsed class
|
||||
private String[] interface_names; // Names of implemented interfaces
|
||||
private ConstantPool constant_pool; // collection of constants
|
||||
private Annotations runtimeVisibleAnnotations; // "RuntimeVisibleAnnotations" attribute defined in the class
|
||||
private static final int BUFSIZE = 8192;
|
||||
|
||||
private static final String[] INTERFACES_EMPTY_ARRAY = new String[0];
|
||||
|
||||
/**
|
||||
* Parses class from the given stream.
|
||||
*
|
||||
* @param inputStream Input stream
|
||||
*/
|
||||
public ClassParser(final InputStream inputStream) {
|
||||
this.dataInputStream = new DataInputStream(new BufferedInputStream(inputStream, BUFSIZE));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the given Java class file and return an object that represents
|
||||
* the contained data, i.e., constants, methods, fields and commands.
|
||||
* A <em>ClassFormatException</em> is raised, if the file is not a valid
|
||||
* .class file. (This does not include verification of the byte code as it
|
||||
* is performed by the java interpreter).
|
||||
*
|
||||
* @return Class object representing the parsed class file
|
||||
* @throws IOException If an I/O occurs reading the byte code
|
||||
* @throws ClassFormatException If the byte code is invalid
|
||||
*/
|
||||
public JavaClass parse() throws IOException, ClassFormatException {
|
||||
/****************** Read headers ********************************/
|
||||
// Check magic tag of class file
|
||||
readID();
|
||||
// Get compiler version
|
||||
readVersion();
|
||||
/****************** Read constant pool and related **************/
|
||||
// Read constant pool entries
|
||||
readConstantPool();
|
||||
// Get class information
|
||||
readClassInfo();
|
||||
// Get interface information, i.e., implemented interfaces
|
||||
readInterfaces();
|
||||
/****************** Read class fields and methods ***************/
|
||||
// Read class fields, i.e., the variables of the class
|
||||
readFields();
|
||||
// Read class methods, i.e., the functions in the class
|
||||
readMethods();
|
||||
// Read class attributes
|
||||
readAttributes();
|
||||
|
||||
// Return the information we have gathered in a new object
|
||||
return new JavaClass(class_name, superclass_name,
|
||||
access_flags, constant_pool, interface_names,
|
||||
runtimeVisibleAnnotations);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads information about the attributes of the class.
|
||||
* @throws IOException
|
||||
* @throws ClassFormatException
|
||||
*/
|
||||
private void readAttributes() throws IOException, ClassFormatException {
|
||||
final int attributes_count = dataInputStream.readUnsignedShort();
|
||||
for (int i = 0; i < attributes_count; i++) {
|
||||
ConstantUtf8 c;
|
||||
String name;
|
||||
int name_index;
|
||||
int length;
|
||||
// Get class name from constant pool via `name_index' indirection
|
||||
name_index = dataInputStream.readUnsignedShort();
|
||||
c = (ConstantUtf8) constant_pool.getConstant(name_index,
|
||||
Const.CONSTANT_Utf8);
|
||||
name = c.getBytes();
|
||||
// Length of data in bytes
|
||||
length = dataInputStream.readInt();
|
||||
|
||||
if (name.equals("RuntimeVisibleAnnotations")) {
|
||||
if (runtimeVisibleAnnotations != null) {
|
||||
throw new ClassFormatException(
|
||||
"RuntimeVisibleAnnotations attribute is not allowed more than once in a class file");
|
||||
}
|
||||
runtimeVisibleAnnotations = new Annotations(dataInputStream, constant_pool);
|
||||
} else {
|
||||
// All other attributes are skipped
|
||||
Utility.skipFully(dataInputStream, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads information about the class and its super class.
|
||||
* @throws IOException
|
||||
* @throws ClassFormatException
|
||||
*/
|
||||
private void readClassInfo() throws IOException, ClassFormatException {
|
||||
access_flags = dataInputStream.readUnsignedShort();
|
||||
/* Interfaces are implicitly abstract, the flag should be set
|
||||
* according to the JVM specification.
|
||||
*/
|
||||
if ((access_flags & Const.ACC_INTERFACE) != 0) {
|
||||
access_flags |= Const.ACC_ABSTRACT;
|
||||
}
|
||||
if (((access_flags & Const.ACC_ABSTRACT) != 0)
|
||||
&& ((access_flags & Const.ACC_FINAL) != 0)) {
|
||||
throw new ClassFormatException("Class can't be both final and abstract");
|
||||
}
|
||||
|
||||
int class_name_index = dataInputStream.readUnsignedShort();
|
||||
class_name = Utility.getClassName(constant_pool, class_name_index);
|
||||
|
||||
int superclass_name_index = dataInputStream.readUnsignedShort();
|
||||
if (superclass_name_index > 0) {
|
||||
// May be zero -> class is java.lang.Object
|
||||
superclass_name = Utility.getClassName(constant_pool, superclass_name_index);
|
||||
} else {
|
||||
superclass_name = "java.lang.Object";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads constant pool entries.
|
||||
* @throws IOException
|
||||
* @throws ClassFormatException
|
||||
*/
|
||||
private void readConstantPool() throws IOException, ClassFormatException {
|
||||
constant_pool = new ConstantPool(dataInputStream);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads information about the fields of the class, i.e., its variables.
|
||||
* @throws IOException
|
||||
* @throws ClassFormatException
|
||||
*/
|
||||
private void readFields() throws IOException, ClassFormatException {
|
||||
final int fields_count = dataInputStream.readUnsignedShort();
|
||||
for (int i = 0; i < fields_count; i++) {
|
||||
Utility.swallowFieldOrMethod(dataInputStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************** Private utility methods **********************/
|
||||
/**
|
||||
* Checks whether the header of the file is ok.
|
||||
* Of course, this has to be the first action on successive file reads.
|
||||
* @throws IOException
|
||||
* @throws ClassFormatException
|
||||
*/
|
||||
private void readID() throws IOException, ClassFormatException {
|
||||
if (dataInputStream.readInt() != MAGIC) {
|
||||
throw new ClassFormatException("It is not a Java .class file");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads information about the interfaces implemented by this class.
|
||||
* @throws IOException
|
||||
* @throws ClassFormatException
|
||||
*/
|
||||
private void readInterfaces() throws IOException, ClassFormatException {
|
||||
final int interfaces_count = dataInputStream.readUnsignedShort();
|
||||
if (interfaces_count > 0) {
|
||||
interface_names = new String[interfaces_count];
|
||||
for (int i = 0; i < interfaces_count; i++) {
|
||||
int index = dataInputStream.readUnsignedShort();
|
||||
interface_names[i] = Utility.getClassName(constant_pool, index);
|
||||
}
|
||||
} else {
|
||||
interface_names = INTERFACES_EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads information about the methods of the class.
|
||||
* @throws IOException
|
||||
* @throws ClassFormatException
|
||||
*/
|
||||
private void readMethods() throws IOException, ClassFormatException {
|
||||
final int methods_count = dataInputStream.readUnsignedShort();
|
||||
for (int i = 0; i < methods_count; i++) {
|
||||
Utility.swallowFieldOrMethod(dataInputStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads major and minor version of compiler which created the file.
|
||||
* @throws IOException
|
||||
* @throws ClassFormatException
|
||||
*/
|
||||
private void readVersion() throws IOException, ClassFormatException {
|
||||
// file.readUnsignedShort(); // Unused minor
|
||||
// file.readUnsignedShort(); // Unused major
|
||||
Utility.skipFully(dataInputStream, 4);
|
||||
}
|
||||
}
|
||||
108
java/org/apache/tomcat/util/bcel/classfile/Constant.java
Normal file
108
java/org/apache/tomcat/util/bcel/classfile/Constant.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* Abstract superclass for classes to represent the different constant types
|
||||
* in the constant pool of a class file. The classes keep closely to
|
||||
* the JVM specification.
|
||||
*
|
||||
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
|
||||
*/
|
||||
public abstract class Constant {
|
||||
|
||||
/* In fact this tag is redundant since we can distinguish different
|
||||
* `Constant' objects by their type, i.e., via `instanceof'. In some
|
||||
* places we will use the tag for switch()es anyway.
|
||||
*
|
||||
* First, we want match the specification as closely as possible. Second we
|
||||
* need the tag as an index to select the corresponding class name from the
|
||||
* `CONSTANT_NAMES' array.
|
||||
*/
|
||||
protected final byte tag;
|
||||
|
||||
Constant(final byte tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Tag of constant, i.e., its type. No setTag() method to avoid
|
||||
* confusion.
|
||||
*/
|
||||
public final byte getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one constant from the given input, the type depends on a tag byte.
|
||||
*
|
||||
* @param dataInput Input stream
|
||||
* @return Constant object
|
||||
* @throws IOException if an I/O error occurs reading from the given {@code dataInput}.
|
||||
* @throws ClassFormatException if the next byte is not recognized
|
||||
*/
|
||||
static Constant readConstant(final DataInput dataInput) throws IOException, ClassFormatException {
|
||||
final byte b = dataInput.readByte(); // Read tag byte
|
||||
int skipSize;
|
||||
switch (b) {
|
||||
case Const.CONSTANT_Class:
|
||||
return new ConstantClass(dataInput);
|
||||
case Const.CONSTANT_Integer:
|
||||
return new ConstantInteger(dataInput);
|
||||
case Const.CONSTANT_Float:
|
||||
return new ConstantFloat(dataInput);
|
||||
case Const.CONSTANT_Long:
|
||||
return new ConstantLong(dataInput);
|
||||
case Const.CONSTANT_Double:
|
||||
return new ConstantDouble(dataInput);
|
||||
case Const.CONSTANT_Utf8:
|
||||
return ConstantUtf8.getInstance(dataInput);
|
||||
case Const.CONSTANT_String:
|
||||
case Const.CONSTANT_MethodType:
|
||||
case Const.CONSTANT_Module:
|
||||
case Const.CONSTANT_Package:
|
||||
skipSize = 2; // unsigned short
|
||||
break;
|
||||
case Const.CONSTANT_MethodHandle:
|
||||
skipSize = 3; // unsigned byte, unsigned short
|
||||
break;
|
||||
case Const.CONSTANT_Fieldref:
|
||||
case Const.CONSTANT_Methodref:
|
||||
case Const.CONSTANT_InterfaceMethodref:
|
||||
case Const.CONSTANT_NameAndType:
|
||||
case Const.CONSTANT_Dynamic:
|
||||
case Const.CONSTANT_InvokeDynamic:
|
||||
skipSize = 4; // unsigned short, unsigned short
|
||||
break;
|
||||
default:
|
||||
throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
|
||||
}
|
||||
Utility.skipFully(dataInput, skipSize);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + tag + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* This class is derived from the abstract {@link Constant}
|
||||
* and represents a reference to a (external) class.
|
||||
*
|
||||
* @see Constant
|
||||
*/
|
||||
public final class ConstantClass extends Constant {
|
||||
|
||||
private final int name_index; // Identical to ConstantString except for the name
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an instance from file data.
|
||||
*
|
||||
* @param dataInput Input stream
|
||||
* @throws IOException if an I/O error occurs reading from the given {@code dataInput}.
|
||||
*/
|
||||
ConstantClass(final DataInput dataInput) throws IOException {
|
||||
super(Const.CONSTANT_Class);
|
||||
this.name_index = dataInput.readUnsignedShort();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Name index in constant pool of class name.
|
||||
*/
|
||||
public int getNameIndex() {
|
||||
return name_index;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* This class is derived from the abstract {@link Constant}
|
||||
* and represents a reference to a Double object.
|
||||
*
|
||||
* @see Constant
|
||||
*/
|
||||
public final class ConstantDouble extends Constant {
|
||||
|
||||
private final double bytes;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize instance from file data.
|
||||
*
|
||||
* @param file Input stream
|
||||
* @throws IOException
|
||||
*/
|
||||
ConstantDouble(final DataInput file) throws IOException {
|
||||
super(Const.CONSTANT_Double);
|
||||
this.bytes = file.readDouble();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return data, i.e., 8 bytes.
|
||||
*/
|
||||
public double getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* This class is derived from the abstract {@link Constant}
|
||||
* and represents a reference to a float object.
|
||||
*
|
||||
* @see Constant
|
||||
*/
|
||||
public final class ConstantFloat extends Constant {
|
||||
|
||||
private final float bytes;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize instance from file data.
|
||||
*
|
||||
* @param file Input stream
|
||||
* @throws IOException
|
||||
*/
|
||||
ConstantFloat(final DataInput file) throws IOException {
|
||||
super(Const.CONSTANT_Float);
|
||||
this.bytes = file.readFloat();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return data, i.e., 4 bytes.
|
||||
*/
|
||||
public float getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* This class is derived from the abstract {@link Constant}
|
||||
* and represents a reference to an int object.
|
||||
*
|
||||
* @see Constant
|
||||
*/
|
||||
public final class ConstantInteger extends Constant {
|
||||
|
||||
private final int bytes;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize instance from file data.
|
||||
*
|
||||
* @param file Input stream
|
||||
* @throws IOException
|
||||
*/
|
||||
ConstantInteger(final DataInput file) throws IOException {
|
||||
super(Const.CONSTANT_Integer);
|
||||
this.bytes = file.readInt();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return data, i.e., 4 bytes.
|
||||
*/
|
||||
public int getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
54
java/org/apache/tomcat/util/bcel/classfile/ConstantLong.java
Normal file
54
java/org/apache/tomcat/util/bcel/classfile/ConstantLong.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* This class is derived from the abstract {@link Constant}
|
||||
* and represents a reference to a long object.
|
||||
*
|
||||
* @see Constant
|
||||
*/
|
||||
public final class ConstantLong extends Constant {
|
||||
|
||||
private final long bytes;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize instance from file data.
|
||||
*
|
||||
* @param input Input stream
|
||||
* @throws IOException
|
||||
*/
|
||||
ConstantLong(final DataInput input) throws IOException {
|
||||
super(Const.CONSTANT_Long);
|
||||
this.bytes = input.readLong();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return data, i.e., 8 bytes.
|
||||
*/
|
||||
public long getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
107
java/org/apache/tomcat/util/bcel/classfile/ConstantPool.java
Normal file
107
java/org/apache/tomcat/util/bcel/classfile/ConstantPool.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* This class represents the constant pool, i.e., a table of constants, of
|
||||
* a parsed classfile. It may contain null references, due to the JVM
|
||||
* specification that skips an entry after an 8-byte constant (double,
|
||||
* long) entry. Those interested in generating constant pools
|
||||
* programatically should see <a href="../generic/ConstantPoolGen.html">
|
||||
* ConstantPoolGen</a>.
|
||||
|
||||
* @see Constant
|
||||
*/
|
||||
public class ConstantPool {
|
||||
|
||||
private final Constant[] constant_pool;
|
||||
|
||||
/**
|
||||
* Reads constants from given input stream.
|
||||
*
|
||||
* @param input Input stream
|
||||
* @throws IOException
|
||||
* @throws ClassFormatException
|
||||
*/
|
||||
ConstantPool(final DataInput input) throws IOException, ClassFormatException {
|
||||
final int constant_pool_count = input.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(input);
|
||||
/* 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.
|
||||
*/
|
||||
if (constant_pool[i] != null) {
|
||||
byte tag = constant_pool[i].getTag();
|
||||
if ((tag == Const.CONSTANT_Double) || (tag == Const.CONSTANT_Long)) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets constant from constant pool.
|
||||
*
|
||||
* @param index Index in constant pool
|
||||
* @return Constant value
|
||||
* @see Constant
|
||||
*/
|
||||
public Constant getConstant( final int index ) {
|
||||
if (index >= constant_pool.length || index < 0) {
|
||||
throw new ClassFormatException("Invalid constant pool reference: " + index
|
||||
+ ". Constant pool size is: " + constant_pool.length);
|
||||
}
|
||||
return constant_pool[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets 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
|
||||
* @throws ClassFormatException If the constant is not of the expected type
|
||||
*/
|
||||
public Constant getConstant( final int index, final byte tag ) throws ClassFormatException {
|
||||
Constant c;
|
||||
c = getConstant(index);
|
||||
if (c == null) {
|
||||
throw new ClassFormatException("Constant pool at index " + index + " is null.");
|
||||
}
|
||||
if (c.getTag() != tag) {
|
||||
throw new ClassFormatException("Expected class `" + Const.getConstantName(tag)
|
||||
+ "' at index " + index + " and got " + c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
56
java/org/apache/tomcat/util/bcel/classfile/ConstantUtf8.java
Normal file
56
java/org/apache/tomcat/util/bcel/classfile/ConstantUtf8.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* This class is derived from the abstract
|
||||
* <A HREF="org.apache.tomcat.util.bcel.classfile.Constant.html">Constant</A> class
|
||||
* and represents a reference to a Utf8 encoded string.
|
||||
*
|
||||
* @see Constant
|
||||
*/
|
||||
public final class ConstantUtf8 extends Constant {
|
||||
|
||||
private final String bytes;
|
||||
|
||||
static ConstantUtf8 getInstance(final DataInput input) throws IOException {
|
||||
return new ConstantUtf8(input.readUTF());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bytes Data
|
||||
*/
|
||||
private ConstantUtf8(final String bytes) {
|
||||
super(Const.CONSTANT_Utf8);
|
||||
if (bytes == null) {
|
||||
throw new IllegalArgumentException("bytes must not be null!");
|
||||
}
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Data converted to string.
|
||||
*/
|
||||
public final String getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
99
java/org/apache/tomcat/util/bcel/classfile/ElementValue.java
Normal file
99
java/org/apache/tomcat/util/bcel/classfile/ElementValue.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class ElementValue
|
||||
{
|
||||
private final int type;
|
||||
|
||||
private final ConstantPool cpool;
|
||||
|
||||
|
||||
ElementValue(final int type, final ConstantPool cpool) {
|
||||
this.type = type;
|
||||
this.cpool = cpool;
|
||||
}
|
||||
|
||||
public abstract String stringifyValue();
|
||||
|
||||
public static final byte STRING = 's';
|
||||
public static final byte ENUM_CONSTANT = 'e';
|
||||
public static final byte CLASS = 'c';
|
||||
public static final byte ANNOTATION = '@';
|
||||
public static final byte ARRAY = '[';
|
||||
public static final byte PRIMITIVE_INT = 'I';
|
||||
public static final byte PRIMITIVE_BYTE = 'B';
|
||||
public static final byte PRIMITIVE_CHAR = 'C';
|
||||
public static final byte PRIMITIVE_DOUBLE = 'D';
|
||||
public static final byte PRIMITIVE_FLOAT = 'F';
|
||||
public static final byte PRIMITIVE_LONG = 'J';
|
||||
public static final byte PRIMITIVE_SHORT = 'S';
|
||||
public static final byte PRIMITIVE_BOOLEAN = 'Z';
|
||||
|
||||
public static ElementValue readElementValue(final DataInput input, final ConstantPool cpool) throws IOException
|
||||
{
|
||||
final byte type = input.readByte();
|
||||
switch (type)
|
||||
{
|
||||
case PRIMITIVE_BYTE:
|
||||
case PRIMITIVE_CHAR:
|
||||
case PRIMITIVE_DOUBLE:
|
||||
case PRIMITIVE_FLOAT:
|
||||
case PRIMITIVE_INT:
|
||||
case PRIMITIVE_LONG:
|
||||
case PRIMITIVE_SHORT:
|
||||
case PRIMITIVE_BOOLEAN:
|
||||
case STRING:
|
||||
return new SimpleElementValue(type, input.readUnsignedShort(), cpool);
|
||||
|
||||
case ENUM_CONSTANT:
|
||||
input.readUnsignedShort(); // Unused type_index
|
||||
return new EnumElementValue(ENUM_CONSTANT, input.readUnsignedShort(), cpool);
|
||||
|
||||
case CLASS:
|
||||
return new ClassElementValue(CLASS, input.readUnsignedShort(), cpool);
|
||||
|
||||
case ANNOTATION:
|
||||
// TODO isRuntimeVisible
|
||||
return new AnnotationElementValue(ANNOTATION, new AnnotationEntry(input, cpool), cpool);
|
||||
|
||||
case ARRAY:
|
||||
final int numArrayVals = input.readUnsignedShort();
|
||||
final ElementValue[] evalues = new ElementValue[numArrayVals];
|
||||
for (int j = 0; j < numArrayVals; j++)
|
||||
{
|
||||
evalues[j] = ElementValue.readElementValue(input, cpool);
|
||||
}
|
||||
return new ArrayElementValue(ARRAY, evalues, cpool);
|
||||
|
||||
default:
|
||||
throw new ClassFormatException(
|
||||
"Unexpected element value kind in annotation: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
final ConstantPool getConstantPool() {
|
||||
return cpool;
|
||||
}
|
||||
|
||||
final int getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* an annotation's element value pair
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
public class ElementValuePair
|
||||
{
|
||||
private final ElementValue elementValue;
|
||||
|
||||
private final ConstantPool constantPool;
|
||||
|
||||
private final int elementNameIndex;
|
||||
|
||||
ElementValuePair(final DataInput file, final ConstantPool constantPool) throws IOException {
|
||||
this.constantPool = constantPool;
|
||||
this.elementNameIndex = file.readUnsignedShort();
|
||||
this.elementValue = ElementValue.readElementValue(file, constantPool);
|
||||
}
|
||||
|
||||
public String getNameString()
|
||||
{
|
||||
final ConstantUtf8 c = (ConstantUtf8) constantPool.getConstant(
|
||||
elementNameIndex, Const.CONSTANT_Utf8);
|
||||
return c.getBytes();
|
||||
}
|
||||
|
||||
public final ElementValue getValue()
|
||||
{
|
||||
return elementValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
public class EnumElementValue extends ElementValue
|
||||
{
|
||||
private final int valueIdx;
|
||||
|
||||
EnumElementValue(final int type, final int valueIdx, final ConstantPool cpool) {
|
||||
super(type, cpool);
|
||||
if (type != ENUM_CONSTANT)
|
||||
throw new RuntimeException(
|
||||
"Only element values of type enum can be built with this ctor - type specified: " + type);
|
||||
this.valueIdx = valueIdx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringifyValue()
|
||||
{
|
||||
final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(valueIdx,
|
||||
Const.CONSTANT_Utf8);
|
||||
return cu8.getBytes();
|
||||
}
|
||||
}
|
||||
102
java/org/apache/tomcat/util/bcel/classfile/JavaClass.java
Normal file
102
java/org/apache/tomcat/util/bcel/classfile/JavaClass.java
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
/**
|
||||
* Represents a Java class, i.e., the data structures, constant pool,
|
||||
* fields, methods and commands contained in a Java .class file.
|
||||
* See <a href="http://docs.oracle.com/javase/specs/">JVM specification</a> for details.
|
||||
* The intent of this class is to represent a parsed or otherwise existing
|
||||
* class file. Those interested in programatically generating classes
|
||||
* should see the <a href="../generic/ClassGen.html">ClassGen</a> class.
|
||||
*/
|
||||
public class JavaClass {
|
||||
|
||||
private final int access_flags;
|
||||
private final String class_name;
|
||||
private final String superclass_name;
|
||||
private final String[] interface_names;
|
||||
private final Annotations runtimeVisibleAnnotations; // "RuntimeVisibleAnnotations" attribute defined in the class
|
||||
|
||||
/**
|
||||
* Constructor gets all contents as arguments.
|
||||
*
|
||||
* @param class_name Name of this class.
|
||||
* @param superclass_name Name of this class's superclass.
|
||||
* @param access_flags Access rights defined by bit flags
|
||||
* @param constant_pool Array of constants
|
||||
* @param interface_names Implemented interfaces
|
||||
* @param runtimeVisibleAnnotations "RuntimeVisibleAnnotations" attribute defined on the Class, or null
|
||||
*/
|
||||
JavaClass(final String class_name, final String superclass_name,
|
||||
final int access_flags, final ConstantPool constant_pool, final String[] interface_names,
|
||||
final Annotations runtimeVisibleAnnotations) {
|
||||
this.access_flags = access_flags;
|
||||
this.runtimeVisibleAnnotations = runtimeVisibleAnnotations;
|
||||
this.class_name = class_name;
|
||||
this.superclass_name = superclass_name;
|
||||
this.interface_names = interface_names;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Access flags of the object aka. "modifiers".
|
||||
*/
|
||||
public final int getAccessFlags() {
|
||||
return access_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return annotations entries from "RuntimeVisibleAnnotations" attribute on
|
||||
* the class, if there is any.
|
||||
*
|
||||
* @return An array of entries or {@code null}
|
||||
*/
|
||||
public AnnotationEntry[] getAnnotationEntries() {
|
||||
if (runtimeVisibleAnnotations != null) {
|
||||
return runtimeVisibleAnnotations.getAnnotationEntries();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Class name.
|
||||
*/
|
||||
public String getClassName() {
|
||||
return class_name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Names of implemented interfaces.
|
||||
*/
|
||||
public String[] getInterfaceNames() {
|
||||
return interface_names;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns the super class name of this class. In the case that this class is
|
||||
* java.lang.Object, it will return itself (java.lang.Object). This is probably incorrect
|
||||
* but isn't fixed at this time to not break existing clients.
|
||||
*
|
||||
* @return Superclass name.
|
||||
*/
|
||||
public String getSuperclassName() {
|
||||
return superclass_name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
public class SimpleElementValue extends ElementValue
|
||||
{
|
||||
private final int index;
|
||||
|
||||
SimpleElementValue(final int type, final int index, final ConstantPool cpool) {
|
||||
super(type, cpool);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Value entry index in the cpool
|
||||
*/
|
||||
public int getIndex()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
// Whatever kind of value it is, return it as a string
|
||||
@Override
|
||||
public String stringifyValue()
|
||||
{
|
||||
final ConstantPool cpool = super.getConstantPool();
|
||||
final int _type = super.getType();
|
||||
switch (_type)
|
||||
{
|
||||
case PRIMITIVE_INT:
|
||||
final ConstantInteger c = (ConstantInteger) cpool.getConstant(getIndex(),
|
||||
Const.CONSTANT_Integer);
|
||||
return Integer.toString(c.getBytes());
|
||||
case PRIMITIVE_LONG:
|
||||
final ConstantLong j = (ConstantLong) cpool.getConstant(getIndex(),
|
||||
Const.CONSTANT_Long);
|
||||
return Long.toString(j.getBytes());
|
||||
case PRIMITIVE_DOUBLE:
|
||||
final ConstantDouble d = (ConstantDouble) cpool.getConstant(getIndex(),
|
||||
Const.CONSTANT_Double);
|
||||
return Double.toString(d.getBytes());
|
||||
case PRIMITIVE_FLOAT:
|
||||
final ConstantFloat f = (ConstantFloat) cpool.getConstant(getIndex(),
|
||||
Const.CONSTANT_Float);
|
||||
return Float.toString(f.getBytes());
|
||||
case PRIMITIVE_SHORT:
|
||||
final ConstantInteger s = (ConstantInteger) cpool.getConstant(getIndex(),
|
||||
Const.CONSTANT_Integer);
|
||||
return Integer.toString(s.getBytes());
|
||||
case PRIMITIVE_BYTE:
|
||||
final ConstantInteger b = (ConstantInteger) cpool.getConstant(getIndex(),
|
||||
Const.CONSTANT_Integer);
|
||||
return Integer.toString(b.getBytes());
|
||||
case PRIMITIVE_CHAR:
|
||||
final ConstantInteger ch = (ConstantInteger) cpool.getConstant(
|
||||
getIndex(), Const.CONSTANT_Integer);
|
||||
return String.valueOf((char)ch.getBytes());
|
||||
case PRIMITIVE_BOOLEAN:
|
||||
final ConstantInteger bo = (ConstantInteger) cpool.getConstant(
|
||||
getIndex(), Const.CONSTANT_Integer);
|
||||
if (bo.getBytes() == 0) {
|
||||
return "false";
|
||||
}
|
||||
return "true";
|
||||
case STRING:
|
||||
final ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(getIndex(),
|
||||
Const.CONSTANT_Utf8);
|
||||
return cu8.getBytes();
|
||||
default:
|
||||
throw new RuntimeException("SimpleElementValue class does not know how to stringify type " + _type);
|
||||
}
|
||||
}
|
||||
}
|
||||
86
java/org/apache/tomcat/util/bcel/classfile/Utility.java
Normal file
86
java/org/apache/tomcat/util/bcel/classfile/Utility.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.bcel.classfile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.tomcat.util.bcel.Const;
|
||||
|
||||
/**
|
||||
* Utility functions that do not really belong to any class in particular.
|
||||
*/
|
||||
final class Utility {
|
||||
|
||||
private Utility() {
|
||||
// Hide default constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorten long class name <em>str</em>, i.e., chop off the <em>prefix</em>,
|
||||
* if the
|
||||
* class name starts with this string and the flag <em>chopit</em> is true.
|
||||
* Slashes <em>/</em> are converted to dots <em>.</em>.
|
||||
*
|
||||
* @param str The long class name
|
||||
* @return Compacted class name
|
||||
*/
|
||||
static String compactClassName(final String str) {
|
||||
return str.replace('/', '.'); // Is `/' on all systems, even DOS
|
||||
}
|
||||
|
||||
static String getClassName(final ConstantPool constant_pool, final int index) {
|
||||
Constant c = constant_pool.getConstant(index, Const.CONSTANT_Class);
|
||||
int i = ((ConstantClass) c).getNameIndex();
|
||||
|
||||
// Finally get the string from the constant pool
|
||||
c = constant_pool.getConstant(i, Const.CONSTANT_Utf8);
|
||||
String name = ((ConstantUtf8) c).getBytes();
|
||||
|
||||
return compactClassName(name);
|
||||
}
|
||||
|
||||
static void skipFully(final DataInput file, final int length) throws IOException {
|
||||
int total = file.skipBytes(length);
|
||||
if (total != length) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
|
||||
static void swallowFieldOrMethod(final DataInput file)
|
||||
throws IOException {
|
||||
// file.readUnsignedShort(); // Unused access flags
|
||||
// file.readUnsignedShort(); // name index
|
||||
// file.readUnsignedShort(); // signature index
|
||||
skipFully(file, 6);
|
||||
|
||||
int attributes_count = file.readUnsignedShort();
|
||||
for (int i = 0; i < attributes_count; i++) {
|
||||
swallowAttribute(file);
|
||||
}
|
||||
}
|
||||
|
||||
static void swallowAttribute(final DataInput file)
|
||||
throws IOException {
|
||||
//file.readUnsignedShort(); // Unused name index
|
||||
skipFully(file, 2);
|
||||
// Length of data in bytes
|
||||
int length = file.readInt();
|
||||
skipFully(file, length);
|
||||
}
|
||||
}
|
||||
27
java/org/apache/tomcat/util/bcel/classfile/package.html
Normal file
27
java/org/apache/tomcat/util/bcel/classfile/package.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<p>
|
||||
This package contains the classes that describe the structure of a
|
||||
Java class file and a class file parser.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
30
java/org/apache/tomcat/util/bcel/package.html
Normal file
30
java/org/apache/tomcat/util/bcel/package.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<p>
|
||||
This package contains basic classes for the
|
||||
<a href="https://commons.apache.org/bcel/">Byte Code Engineering Library</a>
|
||||
and constants defined by the
|
||||
<a href="http://docs.oracle.com/javase/specs/">
|
||||
JVM specification</a>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
181
java/org/apache/tomcat/util/buf/AbstractChunk.java
Normal file
181
java/org/apache/tomcat/util/buf/AbstractChunk.java
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Base class for the *Chunk implementation to reduce duplication.
|
||||
*/
|
||||
public abstract class AbstractChunk implements Cloneable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/*
|
||||
* JVMs may limit the maximum array size to slightly less than
|
||||
* Integer.MAX_VALUE. On markt's desktop the limit is MAX_VALUE - 2.
|
||||
* Comments in the JRE source code for ArrayList and other classes indicate
|
||||
* that it may be as low as MAX_VALUE - 8 on some systems.
|
||||
*/
|
||||
public static final int ARRAY_MAX_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
private int hashCode = 0;
|
||||
protected boolean hasHashCode = false;
|
||||
|
||||
protected boolean isSet;
|
||||
|
||||
private int limit = -1;
|
||||
|
||||
protected int start;
|
||||
protected int end;
|
||||
|
||||
|
||||
/**
|
||||
* Maximum amount of data in this buffer. If -1 or not set, the buffer will
|
||||
* grow to {{@link #ARRAY_MAX_SIZE}. Can be smaller than the current buffer
|
||||
* size ( which will not shrink ). When the limit is reached, the buffer
|
||||
* will be flushed (if out is set) or throw exception.
|
||||
*
|
||||
* @param limit The new limit
|
||||
*/
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
|
||||
protected int getLimitInternal() {
|
||||
if (limit > 0) {
|
||||
return limit;
|
||||
} else {
|
||||
return ARRAY_MAX_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the start position of the data in the buffer
|
||||
*/
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
public void setEnd(int i) {
|
||||
end = i;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Deprecate offset and use start
|
||||
|
||||
public int getOffset() {
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
public void setOffset(int off) {
|
||||
if (end < off) {
|
||||
end = off;
|
||||
}
|
||||
start = off;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the length of the data in the buffer
|
||||
*/
|
||||
public int getLength() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
|
||||
public boolean isNull() {
|
||||
if (end > 0) {
|
||||
return false;
|
||||
}
|
||||
return !isSet;
|
||||
}
|
||||
|
||||
|
||||
public int indexOf(String src, int srcOff, int srcLen, int myOff) {
|
||||
char first = src.charAt(srcOff);
|
||||
|
||||
// Look for first char
|
||||
int srcEnd = srcOff + srcLen;
|
||||
|
||||
mainLoop: for (int i = myOff + start; i <= (end - srcLen); i++) {
|
||||
if (getBufferElement(i) != first) {
|
||||
continue;
|
||||
}
|
||||
// found first char, now look for a match
|
||||
int myPos = i + 1;
|
||||
for (int srcPos = srcOff + 1; srcPos < srcEnd;) {
|
||||
if (getBufferElement(myPos++) != src.charAt(srcPos++)) {
|
||||
continue mainLoop;
|
||||
}
|
||||
}
|
||||
return i - start; // found it
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resets the chunk to an uninitialized state.
|
||||
*/
|
||||
public void recycle() {
|
||||
hasHashCode = false;
|
||||
isSet = false;
|
||||
start = 0;
|
||||
end = 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (hasHashCode) {
|
||||
return hashCode;
|
||||
}
|
||||
int code = 0;
|
||||
|
||||
code = hash();
|
||||
hashCode = code;
|
||||
hasHashCode = true;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
public int hash() {
|
||||
int code = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
code = code * 37 + getBufferElement(i);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
protected abstract int getBufferElement(int index);
|
||||
}
|
||||
103
java/org/apache/tomcat/util/buf/Ascii.java
Normal file
103
java/org/apache/tomcat/util/buf/Ascii.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
/**
|
||||
* This class implements some basic ASCII character handling functions.
|
||||
*
|
||||
* @author dac@eng.sun.com
|
||||
* @author James Todd [gonzo@eng.sun.com]
|
||||
*/
|
||||
public final class Ascii {
|
||||
/*
|
||||
* Character translation tables.
|
||||
*/
|
||||
private static final byte[] toLower = new byte[256];
|
||||
|
||||
/*
|
||||
* Character type tables.
|
||||
*/
|
||||
private static final boolean[] isDigit = new boolean[256];
|
||||
|
||||
private static final long OVERFLOW_LIMIT = Long.MAX_VALUE / 10;
|
||||
|
||||
/*
|
||||
* Initialize character translation and type tables.
|
||||
*/
|
||||
static {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
toLower[i] = (byte)i;
|
||||
}
|
||||
|
||||
for (int lc = 'a'; lc <= 'z'; lc++) {
|
||||
int uc = lc + 'A' - 'a';
|
||||
|
||||
toLower[uc] = (byte)lc;
|
||||
}
|
||||
|
||||
for (int d = '0'; d <= '9'; d++) {
|
||||
isDigit[d] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lower case equivalent of the specified ASCII character.
|
||||
* @param c The char
|
||||
* @return the lower case equivalent char
|
||||
*/
|
||||
public static int toLower(int c) {
|
||||
return toLower[c & 0xff] & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the specified ASCII character is a digit.
|
||||
* @param c The char
|
||||
*/
|
||||
private static boolean isDigit(int c) {
|
||||
return isDigit[c & 0xff];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an unsigned long from the specified subarray of bytes.
|
||||
* @param b the bytes to parse
|
||||
* @param off the start offset of the bytes
|
||||
* @param len the length of the bytes
|
||||
* @return the long value
|
||||
* @exception NumberFormatException if the long format was invalid
|
||||
*/
|
||||
public static long parseLong(byte[] b, int off, int len)
|
||||
throws NumberFormatException
|
||||
{
|
||||
int c;
|
||||
|
||||
if (b == null || len <= 0 || !isDigit(c = b[off++])) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
|
||||
long n = c - '0';
|
||||
while (--len > 0) {
|
||||
if (isDigit(c = b[off++]) &&
|
||||
(n < OVERFLOW_LIMIT || (n == OVERFLOW_LIMIT && (c - '0') < 8))) {
|
||||
n = n * 10 + c - '0';
|
||||
} else {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
95
java/org/apache/tomcat/util/buf/Asn1Parser.java
Normal file
95
java/org/apache/tomcat/util/buf/Asn1Parser.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
|
||||
/**
|
||||
* This is a very basic ASN.1 parser that provides the limited functionality
|
||||
* required by Tomcat. It is a long way from a complete parser.
|
||||
*
|
||||
* TODO: Consider extending this parser and refactoring the SpnegoTokenFixer to
|
||||
* use it.
|
||||
*/
|
||||
public class Asn1Parser {
|
||||
|
||||
private static final StringManager sm = StringManager.getManager(Asn1Parser.class);
|
||||
|
||||
private final byte[] source;
|
||||
|
||||
private int pos = 0;
|
||||
|
||||
|
||||
public Asn1Parser(byte[] source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
public void parseTag(int tag) {
|
||||
int value = next();
|
||||
if (value != tag) {
|
||||
throw new IllegalArgumentException(sm.getString("asn1Parser.tagMismatch",
|
||||
Integer.valueOf(tag), Integer.valueOf(value)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void parseFullLength() {
|
||||
int len = parseLength();
|
||||
if (len + pos != source.length) {
|
||||
throw new IllegalArgumentException(sm.getString("asn1Parser.lengthInvalid",
|
||||
Integer.valueOf(len), Integer.valueOf(source.length - pos)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int parseLength() {
|
||||
int len = next();
|
||||
if (len > 127) {
|
||||
int bytes = len - 128;
|
||||
len = 0;
|
||||
for (int i = 0; i < bytes; i++) {
|
||||
len = len << 8;
|
||||
len = len + next();
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
public BigInteger parseInt() {
|
||||
parseTag(0x02);
|
||||
int len = parseLength();
|
||||
byte[] val = new byte[len];
|
||||
System.arraycopy(source, pos, val, 0, len);
|
||||
pos += len;
|
||||
return new BigInteger(val);
|
||||
}
|
||||
|
||||
|
||||
public void parseBytes(byte[] dest) {
|
||||
System.arraycopy(source, pos, dest, 0, dest.length);
|
||||
pos += dest.length;
|
||||
}
|
||||
|
||||
|
||||
private int next() {
|
||||
return source[pos++] & 0xFF;
|
||||
}
|
||||
}
|
||||
95
java/org/apache/tomcat/util/buf/Asn1Writer.java
Normal file
95
java/org/apache/tomcat/util/buf/Asn1Writer.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
public class Asn1Writer {
|
||||
|
||||
public static byte[] writeSequence(byte[]... components) {
|
||||
int len = 0;
|
||||
for (byte[] component : components) {
|
||||
len += component.length;
|
||||
}
|
||||
|
||||
byte[] combined = new byte[len];
|
||||
int pos = 0;
|
||||
for (byte[] component : components) {
|
||||
System.arraycopy(component, 0, combined, pos, component.length);
|
||||
pos += component.length;
|
||||
}
|
||||
|
||||
return writeTag((byte) 0x30, combined);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] writeInteger(int value) {
|
||||
// How many bytes required to write the value? No more than 4 for int.
|
||||
int valueSize = 1;
|
||||
while ((value >> (valueSize * 8)) > 0) {
|
||||
valueSize++;
|
||||
}
|
||||
|
||||
byte[] valueBytes = new byte[valueSize];
|
||||
int i = 0;
|
||||
while (valueSize > 0) {
|
||||
valueBytes[i] = (byte) (value >> (8 * (valueSize - 1)));
|
||||
value = value >> 8;
|
||||
valueSize--;
|
||||
i++;
|
||||
}
|
||||
|
||||
return writeTag((byte) 0x02, valueBytes);
|
||||
}
|
||||
|
||||
public static byte[] writeOctetString(byte[] data) {
|
||||
return writeTag((byte) 0x04, data);
|
||||
}
|
||||
|
||||
public static byte[] writeTag(byte tagId, byte[] data) {
|
||||
int dataSize = data.length;
|
||||
// How many bytes to write the length?
|
||||
int lengthSize = 1;
|
||||
if (dataSize >127) {
|
||||
// 1 byte we have is now used to record how many bytes we need to
|
||||
// record a length > 127
|
||||
// Result is lengthSize = 1 + number of bytes to record length
|
||||
do {
|
||||
lengthSize++;
|
||||
}
|
||||
while ((dataSize >> (lengthSize * 8)) > 0);
|
||||
}
|
||||
|
||||
// 1 for tag + lengthSize + dataSize
|
||||
byte[] result = new byte[1 + lengthSize + dataSize];
|
||||
result[0] = tagId;
|
||||
if (dataSize < 128) {
|
||||
result[1] = (byte) dataSize;
|
||||
} else {
|
||||
// lengthSize is 1 + number of bytes for length
|
||||
result[1] = (byte) (127 + lengthSize);
|
||||
int i = lengthSize;
|
||||
while (dataSize > 0) {
|
||||
result[i] = (byte) (dataSize & 0xFF);
|
||||
dataSize = dataSize >> 8;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
System.arraycopy(data, 0, result, 1 + lengthSize, data.length);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
284
java/org/apache/tomcat/util/buf/B2CConverter.java
Normal file
284
java/org/apache/tomcat/util/buf/B2CConverter.java
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
|
||||
/**
|
||||
* NIO based character decoder.
|
||||
*/
|
||||
public class B2CConverter {
|
||||
|
||||
private static final StringManager sm =
|
||||
StringManager.getManager(Constants.Package);
|
||||
|
||||
private static final CharsetCache charsetCache = new CharsetCache();
|
||||
|
||||
|
||||
// Protected so unit tests can use it
|
||||
protected static final int LEFTOVER_SIZE = 9;
|
||||
|
||||
/**
|
||||
* Obtain the Charset for the given encoding
|
||||
*
|
||||
* @param enc The name of the encoding for the required charset
|
||||
*
|
||||
* @return The Charset corresponding to the requested encoding
|
||||
*
|
||||
* @throws UnsupportedEncodingException If the requested Charset is not
|
||||
* available
|
||||
*/
|
||||
public static Charset getCharset(String enc)
|
||||
throws UnsupportedEncodingException {
|
||||
|
||||
// Encoding names should all be ASCII
|
||||
String lowerCaseEnc = enc.toLowerCase(Locale.ENGLISH);
|
||||
|
||||
return getCharsetLower(lowerCaseEnc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Only to be used when it is known that the encoding name is in lower case.
|
||||
* @param lowerCaseEnc The name of the encoding for the required charset in
|
||||
* lower case
|
||||
*
|
||||
* @return The Charset corresponding to the requested encoding
|
||||
*
|
||||
* @throws UnsupportedEncodingException If the requested Charset is not
|
||||
* available
|
||||
*
|
||||
* @deprecated Will be removed in Tomcat 9.0.x
|
||||
*/
|
||||
@Deprecated
|
||||
public static Charset getCharsetLower(String lowerCaseEnc)
|
||||
throws UnsupportedEncodingException {
|
||||
|
||||
Charset charset = charsetCache.getCharset(lowerCaseEnc);
|
||||
|
||||
if (charset == null) {
|
||||
// Pre-population of the cache means this must be invalid
|
||||
throw new UnsupportedEncodingException(
|
||||
sm.getString("b2cConverter.unknownEncoding", lowerCaseEnc));
|
||||
}
|
||||
return charset;
|
||||
}
|
||||
|
||||
|
||||
private final CharsetDecoder decoder;
|
||||
private ByteBuffer bb = null;
|
||||
private CharBuffer cb = null;
|
||||
|
||||
/**
|
||||
* Leftover buffer used for incomplete characters.
|
||||
*/
|
||||
private final ByteBuffer leftovers;
|
||||
|
||||
public B2CConverter(Charset charset) {
|
||||
this(charset, false);
|
||||
}
|
||||
|
||||
public B2CConverter(Charset charset, boolean replaceOnError) {
|
||||
byte[] left = new byte[LEFTOVER_SIZE];
|
||||
leftovers = ByteBuffer.wrap(left);
|
||||
CodingErrorAction action;
|
||||
if (replaceOnError) {
|
||||
action = CodingErrorAction.REPLACE;
|
||||
} else {
|
||||
action = CodingErrorAction.REPORT;
|
||||
}
|
||||
// Special case. Use the Apache Harmony based UTF-8 decoder because it
|
||||
// - a) rejects invalid sequences that the JVM decoder does not
|
||||
// - b) fails faster for some invalid sequences
|
||||
if (charset.equals(StandardCharsets.UTF_8)) {
|
||||
decoder = new Utf8Decoder();
|
||||
} else {
|
||||
decoder = charset.newDecoder();
|
||||
}
|
||||
decoder.onMalformedInput(action);
|
||||
decoder.onUnmappableCharacter(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the decoder state.
|
||||
*/
|
||||
public void recycle() {
|
||||
decoder.reset();
|
||||
leftovers.position(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given bytes to characters.
|
||||
*
|
||||
* @param bc byte input
|
||||
* @param cc char output
|
||||
* @param endOfInput Is this all of the available data
|
||||
*
|
||||
* @throws IOException If the conversion can not be completed
|
||||
*/
|
||||
public void convert(ByteChunk bc, CharChunk cc, boolean endOfInput)
|
||||
throws IOException {
|
||||
if ((bb == null) || (bb.array() != bc.getBuffer())) {
|
||||
// Create a new byte buffer if anything changed
|
||||
bb = ByteBuffer.wrap(bc.getBuffer(), bc.getStart(), bc.getLength());
|
||||
} else {
|
||||
// Initialize the byte buffer
|
||||
bb.limit(bc.getEnd());
|
||||
bb.position(bc.getStart());
|
||||
}
|
||||
if ((cb == null) || (cb.array() != cc.getBuffer())) {
|
||||
// Create a new char buffer if anything changed
|
||||
cb = CharBuffer.wrap(cc.getBuffer(), cc.getEnd(),
|
||||
cc.getBuffer().length - cc.getEnd());
|
||||
} else {
|
||||
// Initialize the char buffer
|
||||
cb.limit(cc.getBuffer().length);
|
||||
cb.position(cc.getEnd());
|
||||
}
|
||||
CoderResult result = null;
|
||||
// Parse leftover if any are present
|
||||
if (leftovers.position() > 0) {
|
||||
int pos = cb.position();
|
||||
// Loop until one char is decoded or there is a decoder error
|
||||
do {
|
||||
leftovers.put(bc.substractB());
|
||||
leftovers.flip();
|
||||
result = decoder.decode(leftovers, cb, endOfInput);
|
||||
leftovers.position(leftovers.limit());
|
||||
leftovers.limit(leftovers.array().length);
|
||||
} while (result.isUnderflow() && (cb.position() == pos));
|
||||
if (result.isError() || result.isMalformed()) {
|
||||
result.throwException();
|
||||
}
|
||||
bb.position(bc.getStart());
|
||||
leftovers.position(0);
|
||||
}
|
||||
// Do the decoding and get the results into the byte chunk and the char
|
||||
// chunk
|
||||
result = decoder.decode(bb, cb, endOfInput);
|
||||
if (result.isError() || result.isMalformed()) {
|
||||
result.throwException();
|
||||
} else if (result.isOverflow()) {
|
||||
// Propagate current positions to the byte chunk and char chunk, if
|
||||
// this continues the char buffer will get resized
|
||||
bc.setOffset(bb.position());
|
||||
cc.setEnd(cb.position());
|
||||
} else if (result.isUnderflow()) {
|
||||
// Propagate current positions to the byte chunk and char chunk
|
||||
bc.setOffset(bb.position());
|
||||
cc.setEnd(cb.position());
|
||||
// Put leftovers in the leftovers byte buffer
|
||||
if (bc.getLength() > 0) {
|
||||
leftovers.limit(leftovers.array().length);
|
||||
leftovers.position(bc.getLength());
|
||||
bc.substract(leftovers.array(), 0, bc.getLength());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given bytes to characters.
|
||||
*
|
||||
* @param bc byte input
|
||||
* @param cc char output
|
||||
* @param ic byte input channel
|
||||
* @param endOfInput Is this all of the available data
|
||||
*
|
||||
* @throws IOException If the conversion can not be completed
|
||||
*/
|
||||
public void convert(ByteBuffer bc, CharBuffer cc, ByteChunk.ByteInputChannel ic, boolean endOfInput)
|
||||
throws IOException {
|
||||
if ((bb == null) || (bb.array() != bc.array())) {
|
||||
// Create a new byte buffer if anything changed
|
||||
bb = ByteBuffer.wrap(bc.array(), bc.arrayOffset() + bc.position(), bc.remaining());
|
||||
} else {
|
||||
// Initialize the byte buffer
|
||||
bb.limit(bc.limit());
|
||||
bb.position(bc.position());
|
||||
}
|
||||
if ((cb == null) || (cb.array() != cc.array())) {
|
||||
// Create a new char buffer if anything changed
|
||||
cb = CharBuffer.wrap(cc.array(), cc.limit(), cc.capacity() - cc.limit());
|
||||
} else {
|
||||
// Initialize the char buffer
|
||||
cb.limit(cc.capacity());
|
||||
cb.position(cc.limit());
|
||||
}
|
||||
CoderResult result = null;
|
||||
// Parse leftover if any are present
|
||||
if (leftovers.position() > 0) {
|
||||
int pos = cb.position();
|
||||
// Loop until one char is decoded or there is a decoder error
|
||||
do {
|
||||
byte chr;
|
||||
if (bc.remaining() == 0) {
|
||||
int n = ic.realReadBytes();
|
||||
chr = n < 0 ? -1 : bc.get();
|
||||
} else {
|
||||
chr = bc.get();
|
||||
}
|
||||
leftovers.put(chr);
|
||||
leftovers.flip();
|
||||
result = decoder.decode(leftovers, cb, endOfInput);
|
||||
leftovers.position(leftovers.limit());
|
||||
leftovers.limit(leftovers.array().length);
|
||||
} while (result.isUnderflow() && (cb.position() == pos));
|
||||
if (result.isError() || result.isMalformed()) {
|
||||
result.throwException();
|
||||
}
|
||||
bb.position(bc.position());
|
||||
leftovers.position(0);
|
||||
}
|
||||
// Do the decoding and get the results into the byte chunk and the char
|
||||
// chunk
|
||||
result = decoder.decode(bb, cb, endOfInput);
|
||||
if (result.isError() || result.isMalformed()) {
|
||||
result.throwException();
|
||||
} else if (result.isOverflow()) {
|
||||
// Propagate current positions to the byte chunk and char chunk, if
|
||||
// this continues the char buffer will get resized
|
||||
bc.position(bb.position());
|
||||
cc.limit(cb.position());
|
||||
} else if (result.isUnderflow()) {
|
||||
// Propagate current positions to the byte chunk and char chunk
|
||||
bc.position(bb.position());
|
||||
cc.limit(cb.position());
|
||||
// Put leftovers in the leftovers byte buffer
|
||||
if (bc.remaining() > 0) {
|
||||
leftovers.limit(leftovers.array().length);
|
||||
leftovers.position(bc.remaining());
|
||||
bc.get(leftovers.array(), 0, bc.remaining());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Charset getCharset() {
|
||||
return decoder.charset();
|
||||
}
|
||||
}
|
||||
55
java/org/apache/tomcat/util/buf/ByteBufferHolder.java
Normal file
55
java/org/apache/tomcat/util/buf/ByteBufferHolder.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Simple wrapper for a {@link ByteBuffer} that remembers if the buffer has been
|
||||
* flipped or not.
|
||||
*/
|
||||
public class ByteBufferHolder {
|
||||
|
||||
private final ByteBuffer buf;
|
||||
private final AtomicBoolean flipped;
|
||||
|
||||
public ByteBufferHolder(ByteBuffer buf, boolean flipped) {
|
||||
this.buf = buf;
|
||||
this.flipped = new AtomicBoolean(flipped);
|
||||
}
|
||||
|
||||
|
||||
public ByteBuffer getBuf() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
public boolean isFlipped() {
|
||||
return flipped.get();
|
||||
}
|
||||
|
||||
|
||||
public boolean flip() {
|
||||
if (flipped.compareAndSet(false, true)) {
|
||||
buf.flip();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
144
java/org/apache/tomcat/util/buf/ByteBufferUtils.java
Normal file
144
java/org/apache/tomcat/util/buf/ByteBufferUtils.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
import org.apache.tomcat.util.compat.JreCompat;
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
|
||||
public class ByteBufferUtils {
|
||||
|
||||
private static final StringManager sm =
|
||||
StringManager.getManager(Constants.Package);
|
||||
private static final Log log = LogFactory.getLog(ByteBufferUtils.class);
|
||||
|
||||
private static final Object unsafe;
|
||||
private static final Method cleanerMethod;
|
||||
private static final Method cleanMethod;
|
||||
private static final Method invokeCleanerMethod;
|
||||
|
||||
static {
|
||||
ByteBuffer tempBuffer = ByteBuffer.allocateDirect(0);
|
||||
Method cleanerMethodLocal = null;
|
||||
Method cleanMethodLocal = null;
|
||||
Object unsafeLocal = null;
|
||||
Method invokeCleanerMethodLocal = null;
|
||||
if (JreCompat.isJre9Available()) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("sun.misc.Unsafe");
|
||||
Field theUnsafe = clazz.getDeclaredField("theUnsafe");
|
||||
theUnsafe.setAccessible(true);
|
||||
unsafeLocal = theUnsafe.get(null);
|
||||
invokeCleanerMethodLocal = clazz.getMethod("invokeCleaner", ByteBuffer.class);
|
||||
invokeCleanerMethodLocal.invoke(unsafeLocal, tempBuffer);
|
||||
} catch (IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | NoSuchMethodException | SecurityException
|
||||
| ClassNotFoundException | NoSuchFieldException e) {
|
||||
log.warn(sm.getString("byteBufferUtils.cleaner"), e);
|
||||
unsafeLocal = null;
|
||||
invokeCleanerMethodLocal = null;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
cleanerMethodLocal = tempBuffer.getClass().getMethod("cleaner");
|
||||
cleanerMethodLocal.setAccessible(true);
|
||||
Object cleanerObject = cleanerMethodLocal.invoke(tempBuffer);
|
||||
cleanMethodLocal = cleanerObject.getClass().getMethod("clean");
|
||||
cleanMethodLocal.invoke(cleanerObject);
|
||||
} catch (NoSuchMethodException | SecurityException | IllegalAccessException |
|
||||
IllegalArgumentException | InvocationTargetException e) {
|
||||
log.warn(sm.getString("byteBufferUtils.cleaner"), e);
|
||||
cleanerMethodLocal = null;
|
||||
cleanMethodLocal = null;
|
||||
}
|
||||
}
|
||||
cleanerMethod = cleanerMethodLocal;
|
||||
cleanMethod = cleanMethodLocal;
|
||||
unsafe = unsafeLocal;
|
||||
invokeCleanerMethod = invokeCleanerMethodLocal;
|
||||
}
|
||||
|
||||
private ByteBufferUtils() {
|
||||
// Hide the default constructor since this is a utility class.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expands buffer to the given size unless it is already as big or bigger.
|
||||
* Buffers are assumed to be in 'write to' mode since there would be no need
|
||||
* to expand a buffer while it was in 'read from' mode.
|
||||
*
|
||||
* @param in Buffer to expand
|
||||
* @param newSize The size t which the buffer should be expanded
|
||||
* @return The expanded buffer with any data from the input buffer
|
||||
* copied in to it or the original buffer if there was no
|
||||
* need for expansion
|
||||
*/
|
||||
public static ByteBuffer expand(ByteBuffer in, int newSize) {
|
||||
if (in.capacity() >= newSize) {
|
||||
return in;
|
||||
}
|
||||
|
||||
ByteBuffer out;
|
||||
boolean direct = false;
|
||||
if (in.isDirect()) {
|
||||
out = ByteBuffer.allocateDirect(newSize);
|
||||
direct = true;
|
||||
} else {
|
||||
out = ByteBuffer.allocate(newSize);
|
||||
}
|
||||
|
||||
// Copy data
|
||||
in.flip();
|
||||
out.put(in);
|
||||
|
||||
if (direct) {
|
||||
cleanDirectBuffer(in);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public static void cleanDirectBuffer(ByteBuffer buf) {
|
||||
if (cleanMethod != null) {
|
||||
try {
|
||||
cleanMethod.invoke(cleanerMethod.invoke(buf));
|
||||
} catch (IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | SecurityException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(sm.getString("byteBufferUtils.cleaner"), e);
|
||||
}
|
||||
}
|
||||
} else if (invokeCleanerMethod != null) {
|
||||
try {
|
||||
invokeCleanerMethod.invoke(unsafe, buf);
|
||||
} catch (IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | SecurityException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(sm.getString("byteBufferUtils.cleaner"), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
834
java/org/apache/tomcat/util/buf/ByteChunk.java
Normal file
834
java/org/apache/tomcat/util/buf/ByteChunk.java
Normal file
File diff suppressed because it is too large
Load Diff
192
java/org/apache/tomcat/util/buf/C2BConverter.java
Normal file
192
java/org/apache/tomcat/util/buf/C2BConverter.java
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
|
||||
/**
|
||||
* NIO based character encoder.
|
||||
*/
|
||||
public final class C2BConverter {
|
||||
|
||||
private final CharsetEncoder encoder;
|
||||
private ByteBuffer bb = null;
|
||||
private CharBuffer cb = null;
|
||||
|
||||
/**
|
||||
* Leftover buffer used for multi-characters characters.
|
||||
*/
|
||||
private final CharBuffer leftovers;
|
||||
|
||||
public C2BConverter(Charset charset) {
|
||||
encoder = charset.newEncoder();
|
||||
encoder.onUnmappableCharacter(CodingErrorAction.REPLACE)
|
||||
.onMalformedInput(CodingErrorAction.REPLACE);
|
||||
char[] left = new char[4];
|
||||
leftovers = CharBuffer.wrap(left);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the encoder state.
|
||||
*/
|
||||
public void recycle() {
|
||||
encoder.reset();
|
||||
leftovers.position(0);
|
||||
}
|
||||
|
||||
public boolean isUndeflow() {
|
||||
return (leftovers.position() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given characters to bytes.
|
||||
*
|
||||
* @param cc char input
|
||||
* @param bc byte output
|
||||
* @throws IOException An encoding error occurred
|
||||
*/
|
||||
public void convert(CharChunk cc, ByteChunk bc) throws IOException {
|
||||
if ((bb == null) || (bb.array() != bc.getBuffer())) {
|
||||
// Create a new byte buffer if anything changed
|
||||
bb = ByteBuffer.wrap(bc.getBuffer(), bc.getEnd(), bc.getBuffer().length - bc.getEnd());
|
||||
} else {
|
||||
// Initialize the byte buffer
|
||||
bb.limit(bc.getBuffer().length);
|
||||
bb.position(bc.getEnd());
|
||||
}
|
||||
if ((cb == null) || (cb.array() != cc.getBuffer())) {
|
||||
// Create a new char buffer if anything changed
|
||||
cb = CharBuffer.wrap(cc.getBuffer(), cc.getStart(), cc.getLength());
|
||||
} else {
|
||||
// Initialize the char buffer
|
||||
cb.limit(cc.getEnd());
|
||||
cb.position(cc.getStart());
|
||||
}
|
||||
CoderResult result = null;
|
||||
// Parse leftover if any are present
|
||||
if (leftovers.position() > 0) {
|
||||
int pos = bb.position();
|
||||
// Loop until one char is encoded or there is a encoder error
|
||||
do {
|
||||
leftovers.put((char) cc.substract());
|
||||
leftovers.flip();
|
||||
result = encoder.encode(leftovers, bb, false);
|
||||
leftovers.position(leftovers.limit());
|
||||
leftovers.limit(leftovers.array().length);
|
||||
} while (result.isUnderflow() && (bb.position() == pos));
|
||||
if (result.isError() || result.isMalformed()) {
|
||||
result.throwException();
|
||||
}
|
||||
cb.position(cc.getStart());
|
||||
leftovers.position(0);
|
||||
}
|
||||
// Do the decoding and get the results into the byte chunk and the char
|
||||
// chunk
|
||||
result = encoder.encode(cb, bb, false);
|
||||
if (result.isError() || result.isMalformed()) {
|
||||
result.throwException();
|
||||
} else if (result.isOverflow()) {
|
||||
// Propagate current positions to the byte chunk and char chunk
|
||||
bc.setEnd(bb.position());
|
||||
cc.setOffset(cb.position());
|
||||
} else if (result.isUnderflow()) {
|
||||
// Propagate current positions to the byte chunk and char chunk
|
||||
bc.setEnd(bb.position());
|
||||
cc.setOffset(cb.position());
|
||||
// Put leftovers in the leftovers char buffer
|
||||
if (cc.getLength() > 0) {
|
||||
leftovers.limit(leftovers.array().length);
|
||||
leftovers.position(cc.getLength());
|
||||
cc.substract(leftovers.array(), 0, cc.getLength());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given characters to bytes.
|
||||
*
|
||||
* @param cc char input
|
||||
* @param bc byte output
|
||||
* @throws IOException An encoding error occurred
|
||||
*/
|
||||
public void convert(CharBuffer cc, ByteBuffer bc) throws IOException {
|
||||
if ((bb == null) || (bb.array() != bc.array())) {
|
||||
// Create a new byte buffer if anything changed
|
||||
bb = ByteBuffer.wrap(bc.array(), bc.limit(), bc.capacity() - bc.limit());
|
||||
} else {
|
||||
// Initialize the byte buffer
|
||||
bb.limit(bc.capacity());
|
||||
bb.position(bc.limit());
|
||||
}
|
||||
if ((cb == null) || (cb.array() != cc.array())) {
|
||||
// Create a new char buffer if anything changed
|
||||
cb = CharBuffer.wrap(cc.array(), cc.arrayOffset() + cc.position(), cc.remaining());
|
||||
} else {
|
||||
// Initialize the char buffer
|
||||
cb.limit(cc.limit());
|
||||
cb.position(cc.position());
|
||||
}
|
||||
CoderResult result = null;
|
||||
// Parse leftover if any are present
|
||||
if (leftovers.position() > 0) {
|
||||
int pos = bb.position();
|
||||
// Loop until one char is encoded or there is a encoder error
|
||||
do {
|
||||
leftovers.put(cc.get());
|
||||
leftovers.flip();
|
||||
result = encoder.encode(leftovers, bb, false);
|
||||
leftovers.position(leftovers.limit());
|
||||
leftovers.limit(leftovers.array().length);
|
||||
} while (result.isUnderflow() && (bb.position() == pos));
|
||||
if (result.isError() || result.isMalformed()) {
|
||||
result.throwException();
|
||||
}
|
||||
cb.position(cc.position());
|
||||
leftovers.position(0);
|
||||
}
|
||||
// Do the decoding and get the results into the byte chunk and the char
|
||||
// chunk
|
||||
result = encoder.encode(cb, bb, false);
|
||||
if (result.isError() || result.isMalformed()) {
|
||||
result.throwException();
|
||||
} else if (result.isOverflow()) {
|
||||
// Propagate current positions to the byte chunk and char chunk
|
||||
bc.limit(bb.position());
|
||||
cc.position(cb.position());
|
||||
} else if (result.isUnderflow()) {
|
||||
// Propagate current positions to the byte chunk and char chunk
|
||||
bc.limit(bb.position());
|
||||
cc.position(cb.position());
|
||||
// Put leftovers in the leftovers char buffer
|
||||
if (cc.remaining() > 0) {
|
||||
leftovers.limit(leftovers.array().length);
|
||||
leftovers.position(cc.remaining());
|
||||
cc.get(leftovers.array(), 0, cc.remaining());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Charset getCharset() {
|
||||
return encoder.charset();
|
||||
}
|
||||
}
|
||||
662
java/org/apache/tomcat/util/buf/CharChunk.java
Normal file
662
java/org/apache/tomcat/util/buf/CharChunk.java
Normal file
File diff suppressed because it is too large
Load Diff
230
java/org/apache/tomcat/util/buf/CharsetCache.java
Normal file
230
java/org/apache/tomcat/util/buf/CharsetCache.java
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class CharsetCache {
|
||||
|
||||
/* Note: Package private to enable testing without reflection */
|
||||
static final String[] INITIAL_CHARSETS = new String[] { "iso-8859-1", "utf-8" };
|
||||
|
||||
/*
|
||||
* Note: Package private to enable testing without reflection
|
||||
*/
|
||||
static final String[] LAZY_CHARSETS = new String[] {
|
||||
// Initial set from Oracle JDK 8 u192
|
||||
"037", "1006", "1025", "1026", "1046", "1047", "1089", "1097", "1098", "1112", "1122", "1123", "1124",
|
||||
"1140", "1141", "1142", "1143", "1144", "1145", "1146", "1147", "1148", "1149", "1166", "1364", "1381",
|
||||
"1383", "273", "277", "278", "280", "284", "285", "290", "297", "300", "33722", "420", "424", "437", "500",
|
||||
"5601", "646", "737", "775", "813", "834", "838", "850", "852", "855", "856", "857", "858", "860", "861",
|
||||
"862", "863", "864", "865", "866", "868", "869", "870", "871", "874", "875", "8859_13", "8859_15", "8859_2",
|
||||
"8859_3", "8859_4", "8859_5", "8859_6", "8859_7", "8859_8", "8859_9", "912", "913", "914", "915", "916",
|
||||
"918", "920", "921", "922", "923", "930", "933", "935", "937", "939", "942", "942c", "943", "943c", "948",
|
||||
"949", "949c", "950", "964", "970", "ansi-1251", "ansi_x3.4-1968", "ansi_x3.4-1986", "arabic", "ascii",
|
||||
"ascii7", "asmo-708", "big5", "big5-hkscs", "big5-hkscs", "big5-hkscs-2001", "big5-hkscs:unicode3.0",
|
||||
"big5_hkscs", "big5_hkscs_2001", "big5_solaris", "big5hk", "big5hk-2001", "big5hkscs", "big5hkscs-2001",
|
||||
"ccsid00858", "ccsid01140", "ccsid01141", "ccsid01142", "ccsid01143", "ccsid01144", "ccsid01145",
|
||||
"ccsid01146", "ccsid01147", "ccsid01148", "ccsid01149", "cesu-8", "cesu8", "cns11643", "compound_text",
|
||||
"cp-ar", "cp-gr", "cp-is", "cp00858", "cp01140", "cp01141", "cp01142", "cp01143", "cp01144", "cp01145",
|
||||
"cp01146", "cp01147", "cp01148", "cp01149", "cp037", "cp1006", "cp1025", "cp1026", "cp1046", "cp1047",
|
||||
"cp1089", "cp1097", "cp1098", "cp1112", "cp1122", "cp1123", "cp1124", "cp1140", "cp1141", "cp1142",
|
||||
"cp1143", "cp1144", "cp1145", "cp1146", "cp1147", "cp1148", "cp1149", "cp1166", "cp1250", "cp1251",
|
||||
"cp1252", "cp1253", "cp1254", "cp1255", "cp1256", "cp1257", "cp1258", "cp1364", "cp1381", "cp1383", "cp273",
|
||||
"cp277", "cp278", "cp280", "cp284", "cp285", "cp290", "cp297", "cp300", "cp33722", "cp367", "cp420",
|
||||
"cp424", "cp437", "cp500", "cp50220", "cp50221", "cp5346", "cp5347", "cp5348", "cp5349", "cp5350", "cp5353",
|
||||
"cp737", "cp775", "cp813", "cp833", "cp834", "cp838", "cp850", "cp852", "cp855", "cp856", "cp857", "cp858",
|
||||
"cp860", "cp861", "cp862", "cp863", "cp864", "cp865", "cp866", "cp868", "cp869", "cp870", "cp871", "cp874",
|
||||
"cp875", "cp912", "cp913", "cp914", "cp915", "cp916", "cp918", "cp920", "cp921", "cp922", "cp923", "cp930",
|
||||
"cp933", "cp935", "cp936", "cp937", "cp939", "cp942", "cp942c", "cp943", "cp943c", "cp948", "cp949",
|
||||
"cp949c", "cp950", "cp964", "cp970", "cpibm284", "cpibm285", "cpibm297", "cpibm37", "cs-ebcdic-cp-ca",
|
||||
"cs-ebcdic-cp-nl", "cs-ebcdic-cp-us", "cs-ebcdic-cp-wt", "csascii", "csbig5", "cscesu-8", "cseuckr",
|
||||
"cseucpkdfmtjapanese", "cshalfwidthkatakana", "csibm037", "csibm278", "csibm284", "csibm285", "csibm290",
|
||||
"csibm297", "csibm420", "csibm424", "csibm500", "csibm857", "csibm860", "csibm861", "csibm862", "csibm863",
|
||||
"csibm864", "csibm865", "csibm866", "csibm868", "csibm869", "csibm870", "csibm871", "csiso153gost1976874",
|
||||
"csiso159jisx02121990", "csiso2022cn", "csiso2022jp", "csiso2022jp2", "csiso2022kr", "csiso87jisx0208",
|
||||
"csisolatin0", "csisolatin2", "csisolatin3", "csisolatin4", "csisolatin5", "csisolatin9",
|
||||
"csisolatinarabic", "csisolatincyrillic", "csisolatingreek", "csisolatinhebrew", "csjisencoding", "cskoi8r",
|
||||
"cspc850multilingual", "cspc862latinhebrew", "cspc8codepage437", "cspcp852", "cspcp855", "csshiftjis",
|
||||
"cswindows31j", "cyrillic", "default", "ebcdic-cp-ar1", "ebcdic-cp-ar2", "ebcdic-cp-bh", "ebcdic-cp-ca",
|
||||
"ebcdic-cp-ch", "ebcdic-cp-fr", "ebcdic-cp-gb", "ebcdic-cp-he", "ebcdic-cp-is", "ebcdic-cp-nl",
|
||||
"ebcdic-cp-roece", "ebcdic-cp-se", "ebcdic-cp-us", "ebcdic-cp-wt", "ebcdic-cp-yu", "ebcdic-de-273+euro",
|
||||
"ebcdic-dk-277+euro", "ebcdic-es-284+euro", "ebcdic-fi-278+euro", "ebcdic-fr-277+euro", "ebcdic-gb",
|
||||
"ebcdic-gb-285+euro", "ebcdic-international-500+euro", "ebcdic-it-280+euro", "ebcdic-jp-kana",
|
||||
"ebcdic-no-277+euro", "ebcdic-s-871+euro", "ebcdic-se-278+euro", "ebcdic-sv", "ebcdic-us-037+euro",
|
||||
"ecma-114", "ecma-118", "elot_928", "euc-cn", "euc-jp", "euc-jp-linux", "euc-kr", "euc-tw", "euc_cn",
|
||||
"euc_jp", "euc_jp_linux", "euc_jp_solaris", "euc_kr", "euc_tw", "euccn", "eucjis", "eucjp", "eucjp-open",
|
||||
"euckr", "euctw", "extended_unix_code_packed_format_for_japanese", "gb18030", "gb18030-2000", "gb2312",
|
||||
"gb2312", "gb2312-1980", "gb2312-80", "gbk", "greek", "greek8", "hebrew", "ibm-037", "ibm-1006", "ibm-1025",
|
||||
"ibm-1026", "ibm-1046", "ibm-1047", "ibm-1089", "ibm-1097", "ibm-1098", "ibm-1112", "ibm-1122", "ibm-1123",
|
||||
"ibm-1124", "ibm-1166", "ibm-1364", "ibm-1381", "ibm-1383", "ibm-273", "ibm-277", "ibm-278", "ibm-280",
|
||||
"ibm-284", "ibm-285", "ibm-290", "ibm-297", "ibm-300", "ibm-33722", "ibm-33722_vascii_vpua", "ibm-37",
|
||||
"ibm-420", "ibm-424", "ibm-437", "ibm-500", "ibm-5050", "ibm-737", "ibm-775", "ibm-813", "ibm-833",
|
||||
"ibm-834", "ibm-838", "ibm-850", "ibm-852", "ibm-855", "ibm-856", "ibm-857", "ibm-860", "ibm-861",
|
||||
"ibm-862", "ibm-863", "ibm-864", "ibm-865", "ibm-866", "ibm-868", "ibm-869", "ibm-870", "ibm-871",
|
||||
"ibm-874", "ibm-875", "ibm-912", "ibm-913", "ibm-914", "ibm-915", "ibm-916", "ibm-918", "ibm-920",
|
||||
"ibm-921", "ibm-922", "ibm-923", "ibm-930", "ibm-933", "ibm-935", "ibm-937", "ibm-939", "ibm-942",
|
||||
"ibm-942c", "ibm-943", "ibm-943c", "ibm-948", "ibm-949", "ibm-949c", "ibm-950", "ibm-964", "ibm-970",
|
||||
"ibm-euckr", "ibm-thai", "ibm00858", "ibm01140", "ibm01141", "ibm01142", "ibm01143", "ibm01144", "ibm01145",
|
||||
"ibm01146", "ibm01147", "ibm01148", "ibm01149", "ibm037", "ibm037", "ibm1006", "ibm1025", "ibm1026",
|
||||
"ibm1026", "ibm1046", "ibm1047", "ibm1089", "ibm1097", "ibm1098", "ibm1112", "ibm1122", "ibm1123",
|
||||
"ibm1124", "ibm1166", "ibm1364", "ibm1381", "ibm1383", "ibm273", "ibm273", "ibm277", "ibm277", "ibm278",
|
||||
"ibm278", "ibm280", "ibm280", "ibm284", "ibm284", "ibm285", "ibm285", "ibm290", "ibm290", "ibm297",
|
||||
"ibm297", "ibm300", "ibm33722", "ibm367", "ibm420", "ibm420", "ibm424", "ibm424", "ibm437", "ibm437",
|
||||
"ibm500", "ibm500", "ibm737", "ibm775", "ibm775", "ibm813", "ibm833", "ibm834", "ibm838", "ibm850",
|
||||
"ibm850", "ibm852", "ibm852", "ibm855", "ibm855", "ibm856", "ibm857", "ibm857", "ibm860", "ibm860",
|
||||
"ibm861", "ibm861", "ibm862", "ibm862", "ibm863", "ibm863", "ibm864", "ibm864", "ibm865", "ibm865",
|
||||
"ibm866", "ibm866", "ibm868", "ibm868", "ibm869", "ibm869", "ibm870", "ibm870", "ibm871", "ibm871",
|
||||
"ibm874", "ibm875", "ibm912", "ibm913", "ibm914", "ibm915", "ibm916", "ibm918", "ibm920", "ibm921",
|
||||
"ibm922", "ibm923", "ibm930", "ibm933", "ibm935", "ibm937", "ibm939", "ibm942", "ibm942c", "ibm943",
|
||||
"ibm943c", "ibm948", "ibm949", "ibm949c", "ibm950", "ibm964", "ibm970", "iscii", "iscii91",
|
||||
"iso-10646-ucs-2", "iso-2022-cn", "iso-2022-cn-cns", "iso-2022-cn-gb", "iso-2022-jp", "iso-2022-jp-2",
|
||||
"iso-2022-kr", "iso-8859-11", "iso-8859-13", "iso-8859-15", "iso-8859-15", "iso-8859-2", "iso-8859-3",
|
||||
"iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-9", "iso-ir-101",
|
||||
"iso-ir-109", "iso-ir-110", "iso-ir-126", "iso-ir-127", "iso-ir-138", "iso-ir-144", "iso-ir-148",
|
||||
"iso-ir-153", "iso-ir-159", "iso-ir-6", "iso-ir-87", "iso2022cn", "iso2022cn_cns", "iso2022cn_gb",
|
||||
"iso2022jp", "iso2022jp2", "iso2022kr", "iso646-us", "iso8859-13", "iso8859-15", "iso8859-2", "iso8859-3",
|
||||
"iso8859-4", "iso8859-5", "iso8859-6", "iso8859-7", "iso8859-8", "iso8859-9", "iso8859_11", "iso8859_13",
|
||||
"iso8859_15", "iso8859_15_fdis", "iso8859_2", "iso8859_3", "iso8859_4", "iso8859_5", "iso8859_6",
|
||||
"iso8859_7", "iso8859_8", "iso8859_9", "iso_646.irv:1983", "iso_646.irv:1991", "iso_8859-13", "iso_8859-15",
|
||||
"iso_8859-2", "iso_8859-2:1987", "iso_8859-3", "iso_8859-3:1988", "iso_8859-4", "iso_8859-4:1988",
|
||||
"iso_8859-5", "iso_8859-5:1988", "iso_8859-6", "iso_8859-6:1987", "iso_8859-7", "iso_8859-7:1987",
|
||||
"iso_8859-8", "iso_8859-8:1988", "iso_8859-9", "iso_8859-9:1989", "jis", "jis0201", "jis0208", "jis0212",
|
||||
"jis_c6226-1983", "jis_encoding", "jis_x0201", "jis_x0201", "jis_x0208-1983", "jis_x0212-1990",
|
||||
"jis_x0212-1990", "jisautodetect", "johab", "koi8", "koi8-r", "koi8-u", "koi8_r", "koi8_u",
|
||||
"ks_c_5601-1987", "ksc5601", "ksc5601-1987", "ksc5601-1992", "ksc5601_1987", "ksc5601_1992", "ksc_5601",
|
||||
"l2", "l3", "l4", "l5", "l9", "latin0", "latin2", "latin3", "latin4", "latin5", "latin9", "macarabic",
|
||||
"maccentraleurope", "maccroatian", "maccyrillic", "macdingbat", "macgreek", "machebrew", "maciceland",
|
||||
"macroman", "macromania", "macsymbol", "macthai", "macturkish", "macukraine", "ms-874", "ms1361", "ms50220",
|
||||
"ms50221", "ms874", "ms932", "ms936", "ms949", "ms950", "ms950_hkscs", "ms950_hkscs_xp", "ms_936", "ms_949",
|
||||
"ms_kanji", "pc-multilingual-850+euro", "pck", "shift-jis", "shift_jis", "shift_jis", "sjis",
|
||||
"st_sev_358-88", "sun_eu_greek", "tis-620", "tis620", "tis620.2533", "unicode", "unicodebig",
|
||||
"unicodebigunmarked", "unicodelittle", "unicodelittleunmarked", "us", "us-ascii", "utf-16", "utf-16be",
|
||||
"utf-16le", "utf-32", "utf-32be", "utf-32be-bom", "utf-32le", "utf-32le-bom", "utf16", "utf32", "utf_16",
|
||||
"utf_16be", "utf_16le", "utf_32", "utf_32be", "utf_32be_bom", "utf_32le", "utf_32le_bom", "windows-1250",
|
||||
"windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256",
|
||||
"windows-1257", "windows-1258", "windows-31j", "windows-437", "windows-874", "windows-932", "windows-936",
|
||||
"windows-949", "windows-950", "windows-iso2022jp", "windows949", "x-big5-hkscs-2001", "x-big5-solaris",
|
||||
"x-compound-text", "x-compound_text", "x-euc-cn", "x-euc-jp", "x-euc-jp-linux", "x-euc-tw", "x-eucjp",
|
||||
"x-eucjp-open", "x-ibm1006", "x-ibm1025", "x-ibm1046", "x-ibm1097", "x-ibm1098", "x-ibm1112", "x-ibm1122",
|
||||
"x-ibm1123", "x-ibm1124", "x-ibm1166", "x-ibm1364", "x-ibm1381", "x-ibm1383", "x-ibm300", "x-ibm33722",
|
||||
"x-ibm737", "x-ibm833", "x-ibm834", "x-ibm856", "x-ibm874", "x-ibm875", "x-ibm921", "x-ibm922", "x-ibm930",
|
||||
"x-ibm933", "x-ibm935", "x-ibm937", "x-ibm939", "x-ibm942", "x-ibm942c", "x-ibm943", "x-ibm943c",
|
||||
"x-ibm948", "x-ibm949", "x-ibm949c", "x-ibm950", "x-ibm964", "x-ibm970", "x-iscii91", "x-iso-2022-cn-cns",
|
||||
"x-iso-2022-cn-gb", "x-iso-8859-11", "x-jis0208", "x-jisautodetect", "x-johab", "x-macarabic",
|
||||
"x-maccentraleurope", "x-maccroatian", "x-maccyrillic", "x-macdingbat", "x-macgreek", "x-machebrew",
|
||||
"x-maciceland", "x-macroman", "x-macromania", "x-macsymbol", "x-macthai", "x-macturkish", "x-macukraine",
|
||||
"x-ms932_0213", "x-ms950-hkscs", "x-ms950-hkscs-xp", "x-mswin-936", "x-pck", "x-sjis", "x-sjis_0213",
|
||||
"x-utf-16be", "x-utf-16le", "x-utf-16le-bom", "x-utf-32be", "x-utf-32be-bom", "x-utf-32le",
|
||||
"x-utf-32le-bom", "x-windows-50220", "x-windows-50221", "x-windows-874", "x-windows-949", "x-windows-950",
|
||||
"x-windows-iso2022jp", "x0201", "x0208", "x0212", "x11-compound_text",
|
||||
// Added from Oracle JDK 10.0.2
|
||||
"csiso885915", "csiso885916", "iso-8859-16", "iso-ir-226", "iso_8859-16", "iso_8859-16:2001", "l10",
|
||||
"latin-9", "latin10", "ms932-0213", "ms932:2004", "ms932_0213", "shift_jis:2004", "shift_jis_0213:2004",
|
||||
"sjis-0213", "sjis:2004", "sjis_0213", "sjis_0213:2004", "windows-932-0213", "windows-932:2004",
|
||||
// Added from OpenJDK 11.0.1
|
||||
"932", "cp932", "cpeuccn", "ibm-1252", "ibm-932", "ibm-euccn", "ibm1252", "ibm932", "ibmeuccn", "x-ibm932",
|
||||
// Added from OpenJDK 12 ea28
|
||||
"1129", "cp1129", "ibm-1129", "ibm-euctw", "ibm1129", "x-ibm1129",
|
||||
// Added from OpenJDK 13 ea15
|
||||
"29626c", "833", "cp29626c", "ibm-1140", "ibm-1141", "ibm-1142", "ibm-1143", "ibm-1144", "ibm-1145",
|
||||
"ibm-1146", "ibm-1147", "ibm-1148", "ibm-1149", "ibm-29626c", "ibm-858", "ibm-eucjp", "ibm1140", "ibm1141",
|
||||
"ibm1142", "ibm1143", "ibm1144", "ibm1145", "ibm1146", "ibm1147", "ibm1148", "ibm1149", "ibm29626c",
|
||||
"ibm858", "x-ibm29626c",
|
||||
// Added from HPE JVM 1.8.0.17-hp-ux
|
||||
"cp1051", "cp1386", "cshproman8", "hp-roman8", "ibm-1051", "r8", "roman8", "roman9"
|
||||
};
|
||||
|
||||
private static final Charset DUMMY_CHARSET = new DummyCharset("Dummy", null);
|
||||
|
||||
private ConcurrentMap<String,Charset> cache = new ConcurrentHashMap<>();
|
||||
|
||||
public CharsetCache() {
|
||||
// Pre-populate the cache
|
||||
for (String charsetName : INITIAL_CHARSETS) {
|
||||
Charset charset = Charset.forName(charsetName);
|
||||
addToCache(charsetName, charset);
|
||||
}
|
||||
|
||||
for (String charsetName : LAZY_CHARSETS) {
|
||||
addToCache(charsetName, DUMMY_CHARSET);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addToCache(String name, Charset charset) {
|
||||
cache.put(name, charset);
|
||||
for (String alias : charset.aliases()) {
|
||||
cache.put(alias.toLowerCase(Locale.ENGLISH), charset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Charset getCharset(String charsetName) {
|
||||
String lcCharsetName = charsetName.toLowerCase(Locale.ENGLISH);
|
||||
|
||||
Charset result = cache.get(lcCharsetName);
|
||||
|
||||
if (result == DUMMY_CHARSET) {
|
||||
// Name is known but the Charset is not in the cache
|
||||
Charset charset = Charset.forName(lcCharsetName);
|
||||
if (charset == null) {
|
||||
// Charset not available in this JVM - remove cache entry
|
||||
cache.remove(lcCharsetName);
|
||||
result = null;
|
||||
} else {
|
||||
// Charset is available - populate cache entry
|
||||
addToCache(lcCharsetName, charset);
|
||||
result = charset;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Placeholder Charset implementation for entries that will be loaded lazily
|
||||
* into the cache.
|
||||
*/
|
||||
private static class DummyCharset extends Charset {
|
||||
|
||||
protected DummyCharset(String canonicalName, String[] aliases) {
|
||||
super(canonicalName, aliases);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Charset cs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharsetDecoder newDecoder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharsetEncoder newEncoder() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
java/org/apache/tomcat/util/buf/Constants.java
Normal file
26
java/org/apache/tomcat/util/buf/Constants.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
/**
|
||||
* String constants for the file package.
|
||||
*/
|
||||
public final class Constants {
|
||||
|
||||
public static final String Package = "org.apache.tomcat.util.buf";
|
||||
|
||||
}
|
||||
118
java/org/apache/tomcat/util/buf/HexUtils.java
Normal file
118
java/org/apache/tomcat/util/buf/HexUtils.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.tomcat.util.buf;
|
||||
|
||||
import org.apache.tomcat.util.res.StringManager;
|
||||
|
||||
/**
|
||||
* Tables useful when converting byte arrays to and from strings of hexadecimal
|
||||
* digits.
|
||||
* Code from Ajp11, from Apache's JServ.
|
||||
*
|
||||
* @author Craig R. McClanahan
|
||||
*/
|
||||
public final class HexUtils {
|
||||
|
||||
private static final StringManager sm =
|
||||
StringManager.getManager(Constants.Package);
|
||||
|
||||
// -------------------------------------------------------------- Constants
|
||||
|
||||
/**
|
||||
* Table for HEX to DEC byte translation.
|
||||
*/
|
||||
private static final int[] DEC = {
|
||||
00, 01, 02, 03, 04, 05, 06, 07, 8, 9, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Table for DEC to HEX byte translation.
|
||||
*/
|
||||
private static final byte[] HEX =
|
||||
{ (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
|
||||
(byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
|
||||
(byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
|
||||
|
||||
|
||||
/**
|
||||
* Table for byte to hex string translation.
|
||||
*/
|
||||
private static final char[] hex = "0123456789abcdef".toCharArray();
|
||||
|
||||
|
||||
// --------------------------------------------------------- Static Methods
|
||||
|
||||
public static int getDec(int index) {
|
||||
// Fast for correct values, slower for incorrect ones
|
||||
try {
|
||||
return DEC[index - '0'];
|
||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte getHex(int index) {
|
||||
return HEX[index];
|
||||
}
|
||||
|
||||
|
||||
public static String toHexString(byte[] bytes) {
|
||||
if (null == bytes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(bytes.length << 1);
|
||||
|
||||
for(int i = 0; i < bytes.length; ++i) {
|
||||
sb.append(hex[(bytes[i] & 0xf0) >> 4])
|
||||
.append(hex[(bytes[i] & 0x0f)])
|
||||
;
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public static byte[] fromHexString(String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((input.length() & 1) == 1) {
|
||||
// Odd number of characters
|
||||
throw new IllegalArgumentException(sm.getString("hexUtils.fromHex.oddDigits"));
|
||||
}
|
||||
|
||||
char[] inputChars = input.toCharArray();
|
||||
byte[] result = new byte[input.length() >> 1];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
int upperNibble = getDec(inputChars[2*i]);
|
||||
int lowerNibble = getDec(inputChars[2*i + 1]);
|
||||
if (upperNibble < 0 || lowerNibble < 0) {
|
||||
// Non hex character
|
||||
throw new IllegalArgumentException(sm.getString("hexUtils.fromHex.nonHex"));
|
||||
}
|
||||
result[i] = (byte) ((upperNibble << 4) + lowerNibble);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
34
java/org/apache/tomcat/util/buf/LocalStrings.properties
Normal file
34
java/org/apache/tomcat/util/buf/LocalStrings.properties
Normal file
@@ -0,0 +1,34 @@
|
||||
# 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.
|
||||
|
||||
asn1Parser.lengthInvalid=Invalid length [{0}] bytes reported when the input data length is [{1}] bytes
|
||||
asn1Parser.tagMismatch=Expected to find value [{0}] but found value [{1}]
|
||||
|
||||
b2cConverter.unknownEncoding=The character encoding [{0}] is not supported
|
||||
|
||||
byteBufferUtils.cleaner=Cannot use direct ByteBuffer cleaner, memory leaking may occur
|
||||
|
||||
c2bConverter.recycleFailed=Failed to recycle the C2B Converter. Creating new BufferedWriter, WriteConvertor and IntermediateOutputStream.
|
||||
|
||||
hexUtils.fromHex.nonHex=The input must consist only of hex digits
|
||||
hexUtils.fromHex.oddDigits=The input must consist of an even number of hex digits
|
||||
|
||||
uDecoder.eof=End of file (EOF)
|
||||
uDecoder.noSlash=The encoded slash character is not allowed
|
||||
uDecoder.urlDecode.conversionError=Failed to decode [{0}] using character set [{1}]
|
||||
uDecoder.urlDecode.missingDigit=Failed to decode [{0}] because the % character must be followed by two hexademical digits
|
||||
uDecoder.urlDecode.uee=Unable to URL decode the specified input since the encoding [{0}] is not supported.
|
||||
|
||||
udecoder.urlDecode.iae=It is practical to %nn decode a byte array since how the %nn is encoded will vary by character set
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user