Merge "Add tool for comparing ojluni sources against upstreams"
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index d348239..758b6ce 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -91,7 +91,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-all
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_REQUIRED_MODULES := tzdata
LOCAL_CORE_LIBRARY := true
LOCAL_UNINSTALLABLE_MODULE := true
@@ -109,7 +108,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-oj
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
LOCAL_REQUIRED_MODULES := tzdata
@@ -126,7 +124,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-libart
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
ifeq ($(EMMA_INSTRUMENT),true)
ifneq ($(EMMA_INSTRUMENT_STATIC),true)
@@ -148,7 +145,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-lambda-stubs
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
LOCAL_CORE_LIBRARY := true
@@ -169,7 +165,6 @@
LOCAL_DEX_PREOPT := false
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-oj-testdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
LOCAL_REQUIRED_MODULES := tzdata
@@ -204,7 +199,6 @@
LOCAL_DEX_PREOPT := false
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-libart-testdex
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all
LOCAL_CORE_LIBRARY := true
LOCAL_REQUIRED_MODULES := tzdata
@@ -221,6 +215,9 @@
LOCAL_JAVA_LIBRARIES := core-oj core-libart
LOCAL_DEX_PREOPT := false
include $(BUILD_JAVA_LIBRARY)
+my_filesystemstest_jar := $(intermediates)/filesystemstest.jar
+$(my_filesystemstest_jar): $(LOCAL_BUILT_MODULE)
+ $(call copy-file-to-target)
endif
ifeq ($(LIBCORE_SKIP_TESTS),)
@@ -230,7 +227,7 @@
LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
# Include individual dex.jar files (jars containing resources and a classes.dex) so that they
# be loaded by tests using ClassLoaders but are not in the main classes.dex.
-LOCAL_JAVA_RESOURCE_FILES := $(TARGET_OUT)/framework/filesystemstest.jar
+LOCAL_JAVA_RESOURCE_FILES := $(my_filesystemstest_jar)
LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp bouncycastle
LOCAL_STATIC_JAVA_LIBRARIES := \
@@ -248,7 +245,6 @@
LOCAL_ERROR_PRONE_FLAGS := -Xep:TryFailThrowable:ERROR
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-tests
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
endif
@@ -262,7 +258,6 @@
LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-bcpkix bouncycastle-ocsp
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE := core-tests-support
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
endif
@@ -276,7 +271,6 @@
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE := jsr166-tests
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_STATIC_JAVA_LIBRARY)
endif
@@ -292,7 +286,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-ojtests
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
# jack bug workaround: int[] java.util.stream.StatefulTestOp.-getjava-util-stream-StreamShapeSwitchesValues() is a private synthetic method in an interface which causes a hard verifier error
LOCAL_DEX_PREOPT := false # disable AOT preverification which breaks the build. it will still throw VerifyError at runtime.
include $(BUILD_JAVA_LIBRARY)
@@ -317,7 +310,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-ojtests-public
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
# jack bug workaround: int[] java.util.stream.StatefulTestOp.-getjava-util-stream-StreamShapeSwitchesValues() is a private synthetic method in an interface which causes a hard verifier error
LOCAL_DEX_PREOPT := false # disable AOT preverification which breaks the build. it will still throw VerifyError at runtime.
include $(BUILD_JAVA_LIBRARY)
@@ -330,12 +322,6 @@
ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, dex/src/main)
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := dex-host
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(non_openjdk_java_files) $(openjdk_java_files) $(android_icu4j_src_files) $(openjdk_lambda_stub_files)
LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
@@ -344,7 +330,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-all-hostdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_REQUIRED_MODULES := tzdata-host
LOCAL_CORE_LIBRARY := true
LOCAL_UNINSTALLABLE_MODULE := true
@@ -360,7 +345,6 @@
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-oj-hostdex
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all-hostdex
LOCAL_REQUIRED_MODULES := tzdata-host
LOCAL_CORE_LIBRARY := true
@@ -376,7 +360,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-libart-hostdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-oj-hostdex
LOCAL_REQUIRED_MODULES := tzdata-host
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
@@ -391,7 +374,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-lambda-stubs-hostdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_JAVA_LIBRARIES := core-all-hostdex
LOCAL_CORE_LIBRARY := true
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
@@ -423,7 +405,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-tests-hostdex
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
endif
@@ -444,7 +425,6 @@
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := core-tests-support-hostdex
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
endif
@@ -464,7 +444,6 @@
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_MODULE := core-ojtests-hostdex
- LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
endif
@@ -502,7 +481,6 @@
LOCAL_MODULE_CLASS:=JAVA_LIBRARIES
LOCAL_MODULE := libcore
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
LOCAL_DROIDDOC_OPTIONS := \
-offlinemode \
diff --git a/dex/src/main/java/com/android/dex/Annotation.java b/dex/src/main/java/com/android/dex/Annotation.java
deleted file mode 100644
index e5ef978..0000000
--- a/dex/src/main/java/com/android/dex/Annotation.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import static com.android.dex.EncodedValueReader.ENCODED_ANNOTATION;
-
-/**
- * An annotation.
- */
-public final class Annotation implements Comparable<Annotation> {
- private final Dex dex;
- private final byte visibility;
- private final EncodedValue encodedAnnotation;
-
- public Annotation(Dex dex, byte visibility, EncodedValue encodedAnnotation) {
- this.dex = dex;
- this.visibility = visibility;
- this.encodedAnnotation = encodedAnnotation;
- }
-
- public byte getVisibility() {
- return visibility;
- }
-
- public EncodedValueReader getReader() {
- return new EncodedValueReader(encodedAnnotation, ENCODED_ANNOTATION);
- }
-
- public int getTypeIndex() {
- EncodedValueReader reader = getReader();
- reader.readAnnotation();
- return reader.getAnnotationType();
- }
-
- public void writeTo(Dex.Section out) {
- out.writeByte(visibility);
- encodedAnnotation.writeTo(out);
- }
-
- @Override public int compareTo(Annotation other) {
- return encodedAnnotation.compareTo(other.encodedAnnotation);
- }
-
- @Override public String toString() {
- return dex == null
- ? visibility + " " + getTypeIndex()
- : visibility + " " + dex.typeNames().get(getTypeIndex());
- }
-}
diff --git a/dex/src/main/java/com/android/dex/ClassData.java b/dex/src/main/java/com/android/dex/ClassData.java
deleted file mode 100644
index 840756c..0000000
--- a/dex/src/main/java/com/android/dex/ClassData.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-public final class ClassData {
- private final Field[] staticFields;
- private final Field[] instanceFields;
- private final Method[] directMethods;
- private final Method[] virtualMethods;
-
- public ClassData(Field[] staticFields, Field[] instanceFields,
- Method[] directMethods, Method[] virtualMethods) {
- this.staticFields = staticFields;
- this.instanceFields = instanceFields;
- this.directMethods = directMethods;
- this.virtualMethods = virtualMethods;
- }
-
- public Field[] getStaticFields() {
- return staticFields;
- }
-
- public Field[] getInstanceFields() {
- return instanceFields;
- }
-
- public Method[] getDirectMethods() {
- return directMethods;
- }
-
- public Method[] getVirtualMethods() {
- return virtualMethods;
- }
-
- public Field[] allFields() {
- Field[] result = new Field[staticFields.length + instanceFields.length];
- System.arraycopy(staticFields, 0, result, 0, staticFields.length);
- System.arraycopy(instanceFields, 0, result, staticFields.length, instanceFields.length);
- return result;
- }
-
- public Method[] allMethods() {
- Method[] result = new Method[directMethods.length + virtualMethods.length];
- System.arraycopy(directMethods, 0, result, 0, directMethods.length);
- System.arraycopy(virtualMethods, 0, result, directMethods.length, virtualMethods.length);
- return result;
- }
-
- public static class Field {
- private final int fieldIndex;
- private final int accessFlags;
-
- public Field(int fieldIndex, int accessFlags) {
- this.fieldIndex = fieldIndex;
- this.accessFlags = accessFlags;
- }
-
- public int getFieldIndex() {
- return fieldIndex;
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
- }
-
- public static class Method {
- private final int methodIndex;
- private final int accessFlags;
- private final int codeOffset;
-
- public Method(int methodIndex, int accessFlags, int codeOffset) {
- this.methodIndex = methodIndex;
- this.accessFlags = accessFlags;
- this.codeOffset = codeOffset;
- }
-
- public int getMethodIndex() {
- return methodIndex;
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
-
- public int getCodeOffset() {
- return codeOffset;
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/ClassDef.java b/dex/src/main/java/com/android/dex/ClassDef.java
deleted file mode 100644
index b3225ec..0000000
--- a/dex/src/main/java/com/android/dex/ClassDef.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-/**
- * A type definition.
- */
-public final class ClassDef {
- public static final int NO_INDEX = -1;
- private final Dex buffer;
- private final int offset;
- private final int typeIndex;
- private final int accessFlags;
- private final int supertypeIndex;
- private final int interfacesOffset;
- private final int sourceFileIndex;
- private final int annotationsOffset;
- private final int classDataOffset;
- private final int staticValuesOffset;
-
- public ClassDef(Dex buffer, int offset, int typeIndex, int accessFlags,
- int supertypeIndex, int interfacesOffset, int sourceFileIndex,
- int annotationsOffset, int classDataOffset, int staticValuesOffset) {
- this.buffer = buffer;
- this.offset = offset;
- this.typeIndex = typeIndex;
- this.accessFlags = accessFlags;
- this.supertypeIndex = supertypeIndex;
- this.interfacesOffset = interfacesOffset;
- this.sourceFileIndex = sourceFileIndex;
- this.annotationsOffset = annotationsOffset;
- this.classDataOffset = classDataOffset;
- this.staticValuesOffset = staticValuesOffset;
- }
-
- public int getOffset() {
- return offset;
- }
-
- public int getTypeIndex() {
- return typeIndex;
- }
-
- public int getSupertypeIndex() {
- return supertypeIndex;
- }
-
- public int getInterfacesOffset() {
- return interfacesOffset;
- }
-
- public short[] getInterfaces() {
- return buffer.readTypeList(interfacesOffset).getTypes();
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
-
- public int getSourceFileIndex() {
- return sourceFileIndex;
- }
-
- public int getAnnotationsOffset() {
- return annotationsOffset;
- }
-
- public int getClassDataOffset() {
- return classDataOffset;
- }
-
- public int getStaticValuesOffset() {
- return staticValuesOffset;
- }
-
- @Override public String toString() {
- if (buffer == null) {
- return typeIndex + " " + supertypeIndex;
- }
-
- StringBuilder result = new StringBuilder();
- result.append(buffer.typeNames().get(typeIndex));
- if (supertypeIndex != NO_INDEX) {
- result.append(" extends ").append(buffer.typeNames().get(supertypeIndex));
- }
- return result.toString();
- }
-}
diff --git a/dex/src/main/java/com/android/dex/Code.java b/dex/src/main/java/com/android/dex/Code.java
deleted file mode 100644
index 9258af7..0000000
--- a/dex/src/main/java/com/android/dex/Code.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-public final class Code {
- private final int registersSize;
- private final int insSize;
- private final int outsSize;
- private final int debugInfoOffset;
- private final short[] instructions;
- private final Try[] tries;
- private final CatchHandler[] catchHandlers;
-
- public Code(int registersSize, int insSize, int outsSize, int debugInfoOffset,
- short[] instructions, Try[] tries, CatchHandler[] catchHandlers) {
- this.registersSize = registersSize;
- this.insSize = insSize;
- this.outsSize = outsSize;
- this.debugInfoOffset = debugInfoOffset;
- this.instructions = instructions;
- this.tries = tries;
- this.catchHandlers = catchHandlers;
- }
-
- public int getRegistersSize() {
- return registersSize;
- }
-
- public int getInsSize() {
- return insSize;
- }
-
- public int getOutsSize() {
- return outsSize;
- }
-
- public int getDebugInfoOffset() {
- return debugInfoOffset;
- }
-
- public short[] getInstructions() {
- return instructions;
- }
-
- public Try[] getTries() {
- return tries;
- }
-
- public CatchHandler[] getCatchHandlers() {
- return catchHandlers;
- }
-
- public static class Try {
- final int startAddress;
- final int instructionCount;
- final int catchHandlerIndex;
-
- Try(int startAddress, int instructionCount, int catchHandlerIndex) {
- this.startAddress = startAddress;
- this.instructionCount = instructionCount;
- this.catchHandlerIndex = catchHandlerIndex;
- }
-
- public int getStartAddress() {
- return startAddress;
- }
-
- public int getInstructionCount() {
- return instructionCount;
- }
-
- /**
- * Returns this try's catch handler <strong>index</strong>. Note that
- * this is distinct from the its catch handler <strong>offset</strong>.
- */
- public int getCatchHandlerIndex() {
- return catchHandlerIndex;
- }
- }
-
- public static class CatchHandler {
- final int[] typeIndexes;
- final int[] addresses;
- final int catchAllAddress;
- final int offset;
-
- public CatchHandler(int[] typeIndexes, int[] addresses, int catchAllAddress, int offset) {
- this.typeIndexes = typeIndexes;
- this.addresses = addresses;
- this.catchAllAddress = catchAllAddress;
- this.offset = offset;
- }
-
- public int[] getTypeIndexes() {
- return typeIndexes;
- }
-
- public int[] getAddresses() {
- return addresses;
- }
-
- public int getCatchAllAddress() {
- return catchAllAddress;
- }
-
- public int getOffset() {
- return offset;
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/Dex.java b/dex/src/main/java/com/android/dex/Dex.java
deleted file mode 100644
index 16293262..0000000
--- a/dex/src/main/java/com/android/dex/Dex.java
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.Code.CatchHandler;
-import com.android.dex.Code.Try;
-import com.android.dex.util.ByteInput;
-import com.android.dex.util.ByteOutput;
-import com.android.dex.util.FileUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UTFDataFormatException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.AbstractList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.RandomAccess;
-import java.util.zip.Adler32;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * The bytes of a dex file in memory for reading and writing. All int offsets
- * are unsigned.
- */
-public final class Dex {
- private static final int CHECKSUM_OFFSET = 8;
- private static final int CHECKSUM_SIZE = 4;
- private static final int SIGNATURE_OFFSET = CHECKSUM_OFFSET + CHECKSUM_SIZE;
- private static final int SIGNATURE_SIZE = 20;
- // Provided as a convenience to avoid a memory allocation to benefit Dalvik.
- // Note: libcore.util.EmptyArray cannot be accessed when this code isn't run on Dalvik.
- static final short[] EMPTY_SHORT_ARRAY = new short[0];
-
- private ByteBuffer data;
- private final TableOfContents tableOfContents = new TableOfContents();
- private int nextSectionStart = 0;
- private final StringTable strings = new StringTable();
- private final TypeIndexToDescriptorIndexTable typeIds = new TypeIndexToDescriptorIndexTable();
- private final TypeIndexToDescriptorTable typeNames = new TypeIndexToDescriptorTable();
- private final ProtoIdTable protoIds = new ProtoIdTable();
- private final FieldIdTable fieldIds = new FieldIdTable();
- private final MethodIdTable methodIds = new MethodIdTable();
-
- /**
- * Creates a new dex that reads from {@code data}. It is an error to modify
- * {@code data} after using it to create a dex buffer.
- */
- public Dex(byte[] data) throws IOException {
- this(ByteBuffer.wrap(data));
- }
-
- private Dex(ByteBuffer data) throws IOException {
- this.data = data;
- this.data.order(ByteOrder.LITTLE_ENDIAN);
- this.tableOfContents.readFrom(this);
- }
-
- /**
- * Creates a new empty dex of the specified size.
- */
- public Dex(int byteCount) throws IOException {
- this.data = ByteBuffer.wrap(new byte[byteCount]);
- this.data.order(ByteOrder.LITTLE_ENDIAN);
- }
-
- /**
- * Creates a new dex buffer of the dex in {@code in}, and closes {@code in}.
- */
- public Dex(InputStream in) throws IOException {
- try {
- loadFrom(in);
- } finally {
- in.close();
- }
- }
-
- /**
- * Creates a new dex buffer from the dex file {@code file}.
- */
- public Dex(File file) throws IOException {
- if (FileUtils.hasArchiveSuffix(file.getName())) {
- ZipFile zipFile = new ZipFile(file);
- ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME);
- if (entry != null) {
- try (InputStream inputStream = zipFile.getInputStream(entry)) {
- loadFrom(inputStream);
- }
- zipFile.close();
- } else {
- throw new DexException("Expected " + DexFormat.DEX_IN_JAR_NAME + " in " + file);
- }
- } else if (file.getName().endsWith(".dex")) {
- try (InputStream inputStream = new FileInputStream(file)) {
- loadFrom(inputStream);
- }
- } else {
- throw new DexException("unknown output extension: " + file);
- }
- }
-
- /**
- * It is the caller's responsibility to close {@code in}.
- */
- private void loadFrom(InputStream in) throws IOException {
- ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
- byte[] buffer = new byte[8192];
-
- int count;
- while ((count = in.read(buffer)) != -1) {
- bytesOut.write(buffer, 0, count);
- }
-
- this.data = ByteBuffer.wrap(bytesOut.toByteArray());
- this.data.order(ByteOrder.LITTLE_ENDIAN);
- this.tableOfContents.readFrom(this);
- }
-
- private static void checkBounds(int index, int length) {
- if (index < 0 || index >= length) {
- throw new IndexOutOfBoundsException("index:" + index + ", length=" + length);
- }
- }
-
- public void writeTo(OutputStream out) throws IOException {
- byte[] buffer = new byte[8192];
- ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
- data.clear();
- while (data.hasRemaining()) {
- int count = Math.min(buffer.length, data.remaining());
- data.get(buffer, 0, count);
- out.write(buffer, 0, count);
- }
- }
-
- public void writeTo(File dexOut) throws IOException {
- try (OutputStream out = new FileOutputStream(dexOut)) {
- writeTo(out);
- }
- }
-
- public TableOfContents getTableOfContents() {
- return tableOfContents;
- }
-
- public Section open(int position) {
- if (position < 0 || position >= data.capacity()) {
- throw new IllegalArgumentException("position=" + position
- + " length=" + data.capacity());
- }
- ByteBuffer sectionData = data.duplicate();
- sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?
- sectionData.position(position);
- sectionData.limit(data.capacity());
- return new Section("section", sectionData);
- }
-
- public Section appendSection(int maxByteCount, String name) {
- if ((maxByteCount & 3) != 0) {
- throw new IllegalStateException("Not four byte aligned!");
- }
- int limit = nextSectionStart + maxByteCount;
- ByteBuffer sectionData = data.duplicate();
- sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?
- sectionData.position(nextSectionStart);
- sectionData.limit(limit);
- Section result = new Section(name, sectionData);
- nextSectionStart = limit;
- return result;
- }
-
- public int getLength() {
- return data.capacity();
- }
-
- public int getNextSectionStart() {
- return nextSectionStart;
- }
-
- /**
- * Returns a copy of the the bytes of this dex.
- */
- public byte[] getBytes() {
- ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
- byte[] result = new byte[data.capacity()];
- data.position(0);
- data.get(result);
- return result;
- }
-
- public List<String> strings() {
- return strings;
- }
-
- public List<Integer> typeIds() {
- return typeIds;
- }
-
- public List<String> typeNames() {
- return typeNames;
- }
-
- public List<ProtoId> protoIds() {
- return protoIds;
- }
-
- public List<FieldId> fieldIds() {
- return fieldIds;
- }
-
- public List<MethodId> methodIds() {
- return methodIds;
- }
-
- public Iterable<ClassDef> classDefs() {
- return new ClassDefIterable();
- }
-
- public TypeList readTypeList(int offset) {
- if (offset == 0) {
- return TypeList.EMPTY;
- }
- return open(offset).readTypeList();
- }
-
- public ClassData readClassData(ClassDef classDef) {
- int offset = classDef.getClassDataOffset();
- if (offset == 0) {
- throw new IllegalArgumentException("offset == 0");
- }
- return open(offset).readClassData();
- }
-
- public Code readCode(ClassData.Method method) {
- int offset = method.getCodeOffset();
- if (offset == 0) {
- throw new IllegalArgumentException("offset == 0");
- }
- return open(offset).readCode();
- }
-
- /**
- * Returns the signature of all but the first 32 bytes of this dex. The
- * first 32 bytes of dex files are not specified to be included in the
- * signature.
- */
- public byte[] computeSignature() throws IOException {
- MessageDigest digest;
- try {
- digest = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError();
- }
- byte[] buffer = new byte[8192];
- ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
- data.limit(data.capacity());
- data.position(SIGNATURE_OFFSET + SIGNATURE_SIZE);
- while (data.hasRemaining()) {
- int count = Math.min(buffer.length, data.remaining());
- data.get(buffer, 0, count);
- digest.update(buffer, 0, count);
- }
- return digest.digest();
- }
-
- /**
- * Returns the checksum of all but the first 12 bytes of {@code dex}.
- */
- public int computeChecksum() throws IOException {
- Adler32 adler32 = new Adler32();
- byte[] buffer = new byte[8192];
- ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
- data.limit(data.capacity());
- data.position(CHECKSUM_OFFSET + CHECKSUM_SIZE);
- while (data.hasRemaining()) {
- int count = Math.min(buffer.length, data.remaining());
- data.get(buffer, 0, count);
- adler32.update(buffer, 0, count);
- }
- return (int) adler32.getValue();
- }
-
- /**
- * Generates the signature and checksum of the dex file {@code out} and
- * writes them to the file.
- */
- public void writeHashes() throws IOException {
- open(SIGNATURE_OFFSET).write(computeSignature());
- open(CHECKSUM_OFFSET).writeInt(computeChecksum());
- }
-
- /**
- * Look up a descriptor index from a type index. Cheaper than:
- * {@code open(tableOfContents.typeIds.off + (index * SizeOf.TYPE_ID_ITEM)).readInt();}
- */
- public int descriptorIndexFromTypeIndex(int typeIndex) {
- checkBounds(typeIndex, tableOfContents.typeIds.size);
- int position = tableOfContents.typeIds.off + (SizeOf.TYPE_ID_ITEM * typeIndex);
- return data.getInt(position);
- }
-
-
- public final class Section implements ByteInput, ByteOutput {
- private final String name;
- private final ByteBuffer data;
- private final int initialPosition;
-
- private Section(String name, ByteBuffer data) {
- this.name = name;
- this.data = data;
- this.initialPosition = data.position();
- }
-
- public int getPosition() {
- return data.position();
- }
-
- public int readInt() {
- return data.getInt();
- }
-
- public short readShort() {
- return data.getShort();
- }
-
- public int readUnsignedShort() {
- return readShort() & 0xffff;
- }
-
- public byte readByte() {
- return data.get();
- }
-
- public byte[] readByteArray(int length) {
- byte[] result = new byte[length];
- data.get(result);
- return result;
- }
-
- public short[] readShortArray(int length) {
- if (length == 0) {
- return EMPTY_SHORT_ARRAY;
- }
- short[] result = new short[length];
- for (int i = 0; i < length; i++) {
- result[i] = readShort();
- }
- return result;
- }
-
- public int readUleb128() {
- return Leb128.readUnsignedLeb128(this);
- }
-
- public int readUleb128p1() {
- return Leb128.readUnsignedLeb128(this) - 1;
- }
-
- public int readSleb128() {
- return Leb128.readSignedLeb128(this);
- }
-
- public void writeUleb128p1(int i) {
- writeUleb128(i + 1);
- }
-
- public TypeList readTypeList() {
- int size = readInt();
- short[] types = readShortArray(size);
- alignToFourBytes();
- return new TypeList(Dex.this, types);
- }
-
- public String readString() {
- int offset = readInt();
- int savedPosition = data.position();
- int savedLimit = data.limit();
- data.position(offset);
- data.limit(data.capacity());
- try {
- int expectedLength = readUleb128();
- String result = Mutf8.decode(this, new char[expectedLength]);
- if (result.length() != expectedLength) {
- throw new DexException("Declared length " + expectedLength
- + " doesn't match decoded length of " + result.length());
- }
- return result;
- } catch (UTFDataFormatException e) {
- throw new DexException(e);
- } finally {
- data.position(savedPosition);
- data.limit(savedLimit);
- }
- }
-
- public FieldId readFieldId() {
- int declaringClassIndex = readUnsignedShort();
- int typeIndex = readUnsignedShort();
- int nameIndex = readInt();
- return new FieldId(Dex.this, declaringClassIndex, typeIndex, nameIndex);
- }
-
- public MethodId readMethodId() {
- int declaringClassIndex = readUnsignedShort();
- int protoIndex = readUnsignedShort();
- int nameIndex = readInt();
- return new MethodId(Dex.this, declaringClassIndex, protoIndex, nameIndex);
- }
-
- public ProtoId readProtoId() {
- int shortyIndex = readInt();
- int returnTypeIndex = readInt();
- int parametersOffset = readInt();
- return new ProtoId(Dex.this, shortyIndex, returnTypeIndex, parametersOffset);
- }
-
- public ClassDef readClassDef() {
- int offset = getPosition();
- int type = readInt();
- int accessFlags = readInt();
- int supertype = readInt();
- int interfacesOffset = readInt();
- int sourceFileIndex = readInt();
- int annotationsOffset = readInt();
- int classDataOffset = readInt();
- int staticValuesOffset = readInt();
- return new ClassDef(Dex.this, offset, type, accessFlags, supertype,
- interfacesOffset, sourceFileIndex, annotationsOffset, classDataOffset,
- staticValuesOffset);
- }
-
- private Code readCode() {
- int registersSize = readUnsignedShort();
- int insSize = readUnsignedShort();
- int outsSize = readUnsignedShort();
- int triesSize = readUnsignedShort();
- int debugInfoOffset = readInt();
- int instructionsSize = readInt();
- short[] instructions = readShortArray(instructionsSize);
- Try[] tries;
- CatchHandler[] catchHandlers;
- if (triesSize > 0) {
- if (instructions.length % 2 == 1) {
- readShort(); // padding
- }
-
- /*
- * We can't read the tries until we've read the catch handlers.
- * Unfortunately they're in the opposite order in the dex file
- * so we need to read them out-of-order.
- */
- Section triesSection = open(data.position());
- skip(triesSize * SizeOf.TRY_ITEM);
- catchHandlers = readCatchHandlers();
- tries = triesSection.readTries(triesSize, catchHandlers);
- } else {
- tries = new Try[0];
- catchHandlers = new CatchHandler[0];
- }
- return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions,
- tries, catchHandlers);
- }
-
- private CatchHandler[] readCatchHandlers() {
- int baseOffset = data.position();
- int catchHandlersSize = readUleb128();
- CatchHandler[] result = new CatchHandler[catchHandlersSize];
- for (int i = 0; i < catchHandlersSize; i++) {
- int offset = data.position() - baseOffset;
- result[i] = readCatchHandler(offset);
- }
- return result;
- }
-
- private Try[] readTries(int triesSize, CatchHandler[] catchHandlers) {
- Try[] result = new Try[triesSize];
- for (int i = 0; i < triesSize; i++) {
- int startAddress = readInt();
- int instructionCount = readUnsignedShort();
- int handlerOffset = readUnsignedShort();
- int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset);
- result[i] = new Try(startAddress, instructionCount, catchHandlerIndex);
- }
- return result;
- }
-
- private int findCatchHandlerIndex(CatchHandler[] catchHandlers, int offset) {
- for (int i = 0; i < catchHandlers.length; i++) {
- CatchHandler catchHandler = catchHandlers[i];
- if (catchHandler.getOffset() == offset) {
- return i;
- }
- }
- throw new IllegalArgumentException();
- }
-
- private CatchHandler readCatchHandler(int offset) {
- int size = readSleb128();
- int handlersCount = Math.abs(size);
- int[] typeIndexes = new int[handlersCount];
- int[] addresses = new int[handlersCount];
- for (int i = 0; i < handlersCount; i++) {
- typeIndexes[i] = readUleb128();
- addresses[i] = readUleb128();
- }
- int catchAllAddress = size <= 0 ? readUleb128() : -1;
- return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset);
- }
-
- private ClassData readClassData() {
- int staticFieldsSize = readUleb128();
- int instanceFieldsSize = readUleb128();
- int directMethodsSize = readUleb128();
- int virtualMethodsSize = readUleb128();
- ClassData.Field[] staticFields = readFields(staticFieldsSize);
- ClassData.Field[] instanceFields = readFields(instanceFieldsSize);
- ClassData.Method[] directMethods = readMethods(directMethodsSize);
- ClassData.Method[] virtualMethods = readMethods(virtualMethodsSize);
- return new ClassData(staticFields, instanceFields, directMethods, virtualMethods);
- }
-
- private ClassData.Field[] readFields(int count) {
- ClassData.Field[] result = new ClassData.Field[count];
- int fieldIndex = 0;
- for (int i = 0; i < count; i++) {
- fieldIndex += readUleb128(); // field index diff
- int accessFlags = readUleb128();
- result[i] = new ClassData.Field(fieldIndex, accessFlags);
- }
- return result;
- }
-
- private ClassData.Method[] readMethods(int count) {
- ClassData.Method[] result = new ClassData.Method[count];
- int methodIndex = 0;
- for (int i = 0; i < count; i++) {
- methodIndex += readUleb128(); // method index diff
- int accessFlags = readUleb128();
- int codeOff = readUleb128();
- result[i] = new ClassData.Method(methodIndex, accessFlags, codeOff);
- }
- return result;
- }
-
- /**
- * Returns a byte array containing the bytes from {@code start} to this
- * section's current position.
- */
- private byte[] getBytesFrom(int start) {
- int end = data.position();
- byte[] result = new byte[end - start];
- data.position(start);
- data.get(result);
- return result;
- }
-
- public Annotation readAnnotation() {
- byte visibility = readByte();
- int start = data.position();
- new EncodedValueReader(this, EncodedValueReader.ENCODED_ANNOTATION).skipValue();
- return new Annotation(Dex.this, visibility, new EncodedValue(getBytesFrom(start)));
- }
-
- public EncodedValue readEncodedArray() {
- int start = data.position();
- new EncodedValueReader(this, EncodedValueReader.ENCODED_ARRAY).skipValue();
- return new EncodedValue(getBytesFrom(start));
- }
-
- public void skip(int count) {
- if (count < 0) {
- throw new IllegalArgumentException();
- }
- data.position(data.position() + count);
- }
-
- /**
- * Skips bytes until the position is aligned to a multiple of 4.
- */
- public void alignToFourBytes() {
- data.position((data.position() + 3) & ~3);
- }
-
- /**
- * Writes 0x00 until the position is aligned to a multiple of 4.
- */
- public void alignToFourBytesWithZeroFill() {
- while ((data.position() & 3) != 0) {
- data.put((byte) 0);
- }
- }
-
- public void assertFourByteAligned() {
- if ((data.position() & 3) != 0) {
- throw new IllegalStateException("Not four byte aligned!");
- }
- }
-
- public void write(byte[] bytes) {
- this.data.put(bytes);
- }
-
- public void writeByte(int b) {
- data.put((byte) b);
- }
-
- public void writeShort(short i) {
- data.putShort(i);
- }
-
- public void writeUnsignedShort(int i) {
- short s = (short) i;
- if (i != (s & 0xffff)) {
- throw new IllegalArgumentException("Expected an unsigned short: " + i);
- }
- writeShort(s);
- }
-
- public void write(short[] shorts) {
- for (short s : shorts) {
- writeShort(s);
- }
- }
-
- public void writeInt(int i) {
- data.putInt(i);
- }
-
- public void writeUleb128(int i) {
- try {
- Leb128.writeUnsignedLeb128(this, i);
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new DexException("Section limit " + data.limit() + " exceeded by " + name);
- }
- }
-
- public void writeSleb128(int i) {
- try {
- Leb128.writeSignedLeb128(this, i);
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new DexException("Section limit " + data.limit() + " exceeded by " + name);
- }
- }
-
- public void writeStringData(String value) {
- try {
- int length = value.length();
- writeUleb128(length);
- write(Mutf8.encode(value));
- writeByte(0);
- } catch (UTFDataFormatException e) {
- throw new AssertionError();
- }
- }
-
- public void writeTypeList(TypeList typeList) {
- short[] types = typeList.getTypes();
- writeInt(types.length);
- for (short type : types) {
- writeShort(type);
- }
- alignToFourBytesWithZeroFill();
- }
-
- /**
- * Returns the number of bytes used by this section.
- */
- public int used() {
- return data.position() - initialPosition;
- }
- }
-
- private final class StringTable extends AbstractList<String> implements RandomAccess {
- @Override public String get(int index) {
- checkBounds(index, tableOfContents.stringIds.size);
- return open(tableOfContents.stringIds.off + (index * SizeOf.STRING_ID_ITEM))
- .readString();
- }
- @Override public int size() {
- return tableOfContents.stringIds.size;
- }
- }
-
- private final class TypeIndexToDescriptorIndexTable extends AbstractList<Integer>
- implements RandomAccess {
- @Override public Integer get(int index) {
- return descriptorIndexFromTypeIndex(index);
- }
- @Override public int size() {
- return tableOfContents.typeIds.size;
- }
- }
-
- private final class TypeIndexToDescriptorTable extends AbstractList<String>
- implements RandomAccess {
- @Override public String get(int index) {
- return strings.get(descriptorIndexFromTypeIndex(index));
- }
- @Override public int size() {
- return tableOfContents.typeIds.size;
- }
- }
-
- private final class ProtoIdTable extends AbstractList<ProtoId> implements RandomAccess {
- @Override public ProtoId get(int index) {
- checkBounds(index, tableOfContents.protoIds.size);
- return open(tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * index))
- .readProtoId();
- }
- @Override public int size() {
- return tableOfContents.protoIds.size;
- }
- }
-
- private final class FieldIdTable extends AbstractList<FieldId> implements RandomAccess {
- @Override public FieldId get(int index) {
- checkBounds(index, tableOfContents.fieldIds.size);
- return open(tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * index))
- .readFieldId();
- }
- @Override public int size() {
- return tableOfContents.fieldIds.size;
- }
- }
-
- private final class MethodIdTable extends AbstractList<MethodId> implements RandomAccess {
- @Override public MethodId get(int index) {
- checkBounds(index, tableOfContents.methodIds.size);
- return open(tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * index))
- .readMethodId();
- }
- @Override public int size() {
- return tableOfContents.methodIds.size;
- }
- }
-
- private final class ClassDefIterator implements Iterator<ClassDef> {
- private final Dex.Section in = open(tableOfContents.classDefs.off);
- private int count = 0;
-
- @Override
- public boolean hasNext() {
- return count < tableOfContents.classDefs.size;
- }
- @Override
- public ClassDef next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- count++;
- return in.readClassDef();
- }
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- private final class ClassDefIterable implements Iterable<ClassDef> {
- public Iterator<ClassDef> iterator() {
- return !tableOfContents.classDefs.exists()
- ? Collections.<ClassDef>emptySet().iterator()
- : new ClassDefIterator();
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/DexException.java b/dex/src/main/java/com/android/dex/DexException.java
deleted file mode 100644
index ee0af18..0000000
--- a/dex/src/main/java/com/android/dex/DexException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.ExceptionWithContext;
-
-/**
- * Thrown when there's a format problem reading, writing, or generally
- * processing a dex file.
- */
-public class DexException extends ExceptionWithContext {
- public DexException(String message) {
- super(message);
- }
-
- public DexException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/DexFormat.java b/dex/src/main/java/com/android/dex/DexFormat.java
deleted file mode 100644
index 97771d8..0000000
--- a/dex/src/main/java/com/android/dex/DexFormat.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-/**
- * Constants that show up in and are otherwise related to {@code .dex}
- * files, and helper methods for same.
- */
-public final class DexFormat {
- private DexFormat() {}
-
- /** API level to target in order to generate invoke-polymorphic */
- public static final int API_INVOKE_POLYMORPHIC = 26;
-
- /** API level to target in order to pass through default and static interface methods */
- public static final int API_DEFAULT_INTERFACE_METHODS = 24;
-
- /** API level to target in order to suppress extended opcode usage */
- public static final int API_NO_EXTENDED_OPCODES = 13;
-
- /**
- * API level to target in order to produce the most modern file
- * format
- */
- public static final int API_CURRENT = API_INVOKE_POLYMORPHIC;
-
- /** dex file version number for API level 26 and earlier */
- public static final String VERSION_FOR_API_26 = "038";
-
- /** dex file version number for API level 24 and earlier */
- public static final String VERSION_FOR_API_24 = "037";
-
- /** dex file version number for API level 13 and earlier */
- public static final String VERSION_FOR_API_13 = "035";
-
- /**
- * Dex file version number for dalvik.
- * <p>
- * Note: Dex version 36 was loadable in some versions of Dalvik but was never fully supported or
- * completed and is not considered a valid dex file format.
- * </p>
- */
- public static final String VERSION_CURRENT = VERSION_FOR_API_26;
-
- /**
- * file name of the primary {@code .dex} file inside an
- * application or library {@code .jar} file
- */
- public static final String DEX_IN_JAR_NAME = "classes.dex";
-
- /** common prefix for all dex file "magic numbers" */
- public static final String MAGIC_PREFIX = "dex\n";
-
- /** common suffix for all dex file "magic numbers" */
- public static final String MAGIC_SUFFIX = "\0";
-
- /**
- * value used to indicate endianness of file contents
- */
- public static final int ENDIAN_TAG = 0x12345678;
-
- /**
- * Maximum addressable field or method index.
- * The largest addressable member is 0xffff, in the "instruction formats" spec as field@CCCC or
- * meth@CCCC.
- */
- public static final int MAX_MEMBER_IDX = 0xFFFF;
-
- /**
- * Maximum addressable type index.
- * The largest addressable type is 0xffff, in the "instruction formats" spec as type@CCCC.
- */
- public static final int MAX_TYPE_IDX = 0xFFFF;
-
- /**
- * Returns the API level corresponding to the given magic number,
- * or {@code -1} if the given array is not a well-formed dex file
- * magic number.
- */
- public static int magicToApi(byte[] magic) {
- if (magic.length != 8) {
- return -1;
- }
-
- if ((magic[0] != 'd') || (magic[1] != 'e') || (magic[2] != 'x') || (magic[3] != '\n') ||
- (magic[7] != '\0')) {
- return -1;
- }
-
- String version = "" + ((char) magic[4]) + ((char) magic[5]) +((char) magic[6]);
-
- if (version.equals(VERSION_FOR_API_13)) {
- return API_NO_EXTENDED_OPCODES;
- } else if (version.equals(VERSION_FOR_API_24)) {
- return API_DEFAULT_INTERFACE_METHODS;
- } else if (version.equals(VERSION_FOR_API_26)) {
- return API_INVOKE_POLYMORPHIC;
- } else if (version.equals(VERSION_CURRENT)) {
- return API_CURRENT;
- }
-
- return -1;
- }
-
- /**
- * Returns the magic number corresponding to the given target API level.
- */
- public static String apiToMagic(int targetApiLevel) {
- String version;
-
- if (targetApiLevel >= API_CURRENT) {
- version = VERSION_CURRENT;
- } else if (targetApiLevel >= API_INVOKE_POLYMORPHIC) {
- version = VERSION_FOR_API_26;
- } else if (targetApiLevel >= API_DEFAULT_INTERFACE_METHODS) {
- version = VERSION_FOR_API_24;
- } else {
- version = VERSION_FOR_API_13;
- }
-
- return MAGIC_PREFIX + version + MAGIC_SUFFIX;
- }
-
- public static boolean isSupportedDexMagic(byte[] magic) {
- int api = magicToApi(magic);
- return api > 0;
- }
-}
diff --git a/dex/src/main/java/com/android/dex/DexIndexOverflowException.java b/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
deleted file mode 100644
index 3226207..0000000
--- a/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-/**
- * Thrown when there's an index overflow writing a dex file.
- */
-public final class DexIndexOverflowException extends DexException {
- public DexIndexOverflowException(String message) {
- super(message);
- }
-
- public DexIndexOverflowException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/EncodedValue.java b/dex/src/main/java/com/android/dex/EncodedValue.java
deleted file mode 100644
index 8d0c3ad..0000000
--- a/dex/src/main/java/com/android/dex/EncodedValue.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.ByteArrayByteInput;
-import com.android.dex.util.ByteInput;
-
-/**
- * An encoded value or array.
- */
-public final class EncodedValue implements Comparable<EncodedValue> {
- private final byte[] data;
-
- public EncodedValue(byte[] data) {
- this.data = data;
- }
-
- public ByteInput asByteInput() {
- return new ByteArrayByteInput(data);
- }
-
- public byte[] getBytes() {
- return data;
- }
-
- public void writeTo(Dex.Section out) {
- out.write(data);
- }
-
- @Override public int compareTo(EncodedValue other) {
- int size = Math.min(data.length, other.data.length);
- for (int i = 0; i < size; i++) {
- if (data[i] != other.data[i]) {
- return (data[i] & 0xff) - (other.data[i] & 0xff);
- }
- }
- return data.length - other.data.length;
- }
-
- @Override public String toString() {
- return Integer.toHexString(data[0] & 0xff) + "...(" + data.length + ")";
- }
-}
diff --git a/dex/src/main/java/com/android/dex/EncodedValueCodec.java b/dex/src/main/java/com/android/dex/EncodedValueCodec.java
deleted file mode 100644
index 7fc1724..0000000
--- a/dex/src/main/java/com/android/dex/EncodedValueCodec.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.ByteInput;
-import com.android.dex.util.ByteOutput;
-
-/**
- * Read and write {@code encoded_value} primitives.
- */
-public final class EncodedValueCodec {
- private EncodedValueCodec() {
- }
-
- /**
- * Writes a signed integral to {@code out}.
- */
- public static void writeSignedIntegralValue(ByteOutput out, int type, long value) {
- /*
- * Figure out how many bits are needed to represent the value,
- * including a sign bit: The bit count is subtracted from 65
- * and not 64 to account for the sign bit. The xor operation
- * has the effect of leaving non-negative values alone and
- * unary complementing negative values (so that a leading zero
- * count always returns a useful number for our present
- * purpose).
- */
- int requiredBits = 65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
-
- // Round up the requiredBits to a number of bytes.
- int requiredBytes = (requiredBits + 0x07) >> 3;
-
- /*
- * Write the header byte, which includes the type and
- * requiredBytes - 1.
- */
- out.writeByte(type | ((requiredBytes - 1) << 5));
-
- // Write the value, per se.
- while (requiredBytes > 0) {
- out.writeByte((byte) value);
- value >>= 8;
- requiredBytes--;
- }
- }
-
- /**
- * Writes an unsigned integral to {@code out}.
- */
- public static void writeUnsignedIntegralValue(ByteOutput out, int type, long value) {
- // Figure out how many bits are needed to represent the value.
- int requiredBits = 64 - Long.numberOfLeadingZeros(value);
- if (requiredBits == 0) {
- requiredBits = 1;
- }
-
- // Round up the requiredBits to a number of bytes.
- int requiredBytes = (requiredBits + 0x07) >> 3;
-
- /*
- * Write the header byte, which includes the type and
- * requiredBytes - 1.
- */
- out.writeByte(type | ((requiredBytes - 1) << 5));
-
- // Write the value, per se.
- while (requiredBytes > 0) {
- out.writeByte((byte) value);
- value >>= 8;
- requiredBytes--;
- }
- }
-
- /**
- * Writes a right-zero-extended value to {@code out}.
- */
- public static void writeRightZeroExtendedValue(ByteOutput out, int type, long value) {
- // Figure out how many bits are needed to represent the value.
- int requiredBits = 64 - Long.numberOfTrailingZeros(value);
- if (requiredBits == 0) {
- requiredBits = 1;
- }
-
- // Round up the requiredBits to a number of bytes.
- int requiredBytes = (requiredBits + 0x07) >> 3;
-
- // Scootch the first bits to be written down to the low-order bits.
- value >>= 64 - (requiredBytes * 8);
-
- /*
- * Write the header byte, which includes the type and
- * requiredBytes - 1.
- */
- out.writeByte(type | ((requiredBytes - 1) << 5));
-
- // Write the value, per se.
- while (requiredBytes > 0) {
- out.writeByte((byte) value);
- value >>= 8;
- requiredBytes--;
- }
- }
-
- /**
- * Read a signed integer.
- *
- * @param zwidth byte count minus one
- */
- public static int readSignedInt(ByteInput in, int zwidth) {
- int result = 0;
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
- }
- result >>= (3 - zwidth) * 8;
- return result;
- }
-
- /**
- * Read an unsigned integer.
- *
- * @param zwidth byte count minus one
- * @param fillOnRight true to zero fill on the right; false on the left
- */
- public static int readUnsignedInt(ByteInput in, int zwidth, boolean fillOnRight) {
- int result = 0;
- if (!fillOnRight) {
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
- }
- result >>>= (3 - zwidth) * 8;
- } else {
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
- }
- }
- return result;
- }
-
- /**
- * Read a signed long.
- *
- * @param zwidth byte count minus one
- */
- public static long readSignedLong(ByteInput in, int zwidth) {
- long result = 0;
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
- }
- result >>= (7 - zwidth) * 8;
- return result;
- }
-
- /**
- * Read an unsigned long.
- *
- * @param zwidth byte count minus one
- * @param fillOnRight true to zero fill on the right; false on the left
- */
- public static long readUnsignedLong(ByteInput in, int zwidth, boolean fillOnRight) {
- long result = 0;
- if (!fillOnRight) {
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
- }
- result >>>= (7 - zwidth) * 8;
- } else {
- for (int i = zwidth; i >= 0; i--) {
- result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
- }
- }
- return result;
- }
-}
diff --git a/dex/src/main/java/com/android/dex/EncodedValueReader.java b/dex/src/main/java/com/android/dex/EncodedValueReader.java
deleted file mode 100644
index 6f60538..0000000
--- a/dex/src/main/java/com/android/dex/EncodedValueReader.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.ByteInput;
-
-/**
- * Pull parser for encoded values.
- */
-public final class EncodedValueReader {
- public static final int ENCODED_BYTE = 0x00;
- public static final int ENCODED_SHORT = 0x02;
- public static final int ENCODED_CHAR = 0x03;
- public static final int ENCODED_INT = 0x04;
- public static final int ENCODED_LONG = 0x06;
- public static final int ENCODED_FLOAT = 0x10;
- public static final int ENCODED_DOUBLE = 0x11;
- public static final int ENCODED_STRING = 0x17;
- public static final int ENCODED_TYPE = 0x18;
- public static final int ENCODED_FIELD = 0x19;
- public static final int ENCODED_ENUM = 0x1b;
- public static final int ENCODED_METHOD = 0x1a;
- public static final int ENCODED_ARRAY = 0x1c;
- public static final int ENCODED_ANNOTATION = 0x1d;
- public static final int ENCODED_NULL = 0x1e;
- public static final int ENCODED_BOOLEAN = 0x1f;
-
- /** placeholder type if the type is not yet known */
- private static final int MUST_READ = -1;
-
- protected final ByteInput in;
- private int type = MUST_READ;
- private int annotationType;
- private int arg;
-
- public EncodedValueReader(ByteInput in) {
- this.in = in;
- }
-
- public EncodedValueReader(EncodedValue in) {
- this(in.asByteInput());
- }
-
- /**
- * Creates a new encoded value reader whose only value is the specified
- * known type. This is useful for encoded values without a type prefix,
- * such as class_def_item's encoded_array or annotation_item's
- * encoded_annotation.
- */
- public EncodedValueReader(ByteInput in, int knownType) {
- this.in = in;
- this.type = knownType;
- }
-
- public EncodedValueReader(EncodedValue in, int knownType) {
- this(in.asByteInput(), knownType);
- }
-
- /**
- * Returns the type of the next value to read.
- */
- public int peek() {
- if (type == MUST_READ) {
- int argAndType = in.readByte() & 0xff;
- type = argAndType & 0x1f;
- arg = (argAndType & 0xe0) >> 5;
- }
- return type;
- }
-
- /**
- * Begins reading the elements of an array, returning the array's size. The
- * caller must follow up by calling a read method for each element in the
- * array. For example, this reads a byte array: <pre> {@code
- * int arraySize = readArray();
- * for (int i = 0, i < arraySize; i++) {
- * readByte();
- * }
- * }</pre>
- */
- public int readArray() {
- checkType(ENCODED_ARRAY);
- type = MUST_READ;
- return Leb128.readUnsignedLeb128(in);
- }
-
- /**
- * Begins reading the fields of an annotation, returning the number of
- * fields. The caller must follow up by making alternating calls to {@link
- * #readAnnotationName()} and another read method. For example, this reads
- * an annotation whose fields are all bytes: <pre> {@code
- * int fieldCount = readAnnotation();
- * int annotationType = getAnnotationType();
- * for (int i = 0; i < fieldCount; i++) {
- * readAnnotationName();
- * readByte();
- * }
- * }</pre>
- */
- public int readAnnotation() {
- checkType(ENCODED_ANNOTATION);
- type = MUST_READ;
- annotationType = Leb128.readUnsignedLeb128(in);
- return Leb128.readUnsignedLeb128(in);
- }
-
- /**
- * Returns the type of the annotation just returned by {@link
- * #readAnnotation()}. This method's value is undefined unless the most
- * recent call was to {@link #readAnnotation()}.
- */
- public int getAnnotationType() {
- return annotationType;
- }
-
- public int readAnnotationName() {
- return Leb128.readUnsignedLeb128(in);
- }
-
- public byte readByte() {
- checkType(ENCODED_BYTE);
- type = MUST_READ;
- return (byte) EncodedValueCodec.readSignedInt(in, arg);
- }
-
- public short readShort() {
- checkType(ENCODED_SHORT);
- type = MUST_READ;
- return (short) EncodedValueCodec.readSignedInt(in, arg);
- }
-
- public char readChar() {
- checkType(ENCODED_CHAR);
- type = MUST_READ;
- return (char) EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readInt() {
- checkType(ENCODED_INT);
- type = MUST_READ;
- return EncodedValueCodec.readSignedInt(in, arg);
- }
-
- public long readLong() {
- checkType(ENCODED_LONG);
- type = MUST_READ;
- return EncodedValueCodec.readSignedLong(in, arg);
- }
-
- public float readFloat() {
- checkType(ENCODED_FLOAT);
- type = MUST_READ;
- return Float.intBitsToFloat(EncodedValueCodec.readUnsignedInt(in, arg, true));
- }
-
- public double readDouble() {
- checkType(ENCODED_DOUBLE);
- type = MUST_READ;
- return Double.longBitsToDouble(EncodedValueCodec.readUnsignedLong(in, arg, true));
- }
-
- public int readString() {
- checkType(ENCODED_STRING);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readType() {
- checkType(ENCODED_TYPE);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readField() {
- checkType(ENCODED_FIELD);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readEnum() {
- checkType(ENCODED_ENUM);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public int readMethod() {
- checkType(ENCODED_METHOD);
- type = MUST_READ;
- return EncodedValueCodec.readUnsignedInt(in, arg, false);
- }
-
- public void readNull() {
- checkType(ENCODED_NULL);
- type = MUST_READ;
- }
-
- public boolean readBoolean() {
- checkType(ENCODED_BOOLEAN);
- type = MUST_READ;
- return arg != 0;
- }
-
- /**
- * Skips a single value, including its nested values if it is an array or
- * annotation.
- */
- public void skipValue() {
- switch (peek()) {
- case ENCODED_BYTE:
- readByte();
- break;
- case ENCODED_SHORT:
- readShort();
- break;
- case ENCODED_CHAR:
- readChar();
- break;
- case ENCODED_INT:
- readInt();
- break;
- case ENCODED_LONG:
- readLong();
- break;
- case ENCODED_FLOAT:
- readFloat();
- break;
- case ENCODED_DOUBLE:
- readDouble();
- break;
- case ENCODED_STRING:
- readString();
- break;
- case ENCODED_TYPE:
- readType();
- break;
- case ENCODED_FIELD:
- readField();
- break;
- case ENCODED_ENUM:
- readEnum();
- break;
- case ENCODED_METHOD:
- readMethod();
- break;
- case ENCODED_ARRAY:
- for (int i = 0, size = readArray(); i < size; i++) {
- skipValue();
- }
- break;
- case ENCODED_ANNOTATION:
- for (int i = 0, size = readAnnotation(); i < size; i++) {
- readAnnotationName();
- skipValue();
- }
- break;
- case ENCODED_NULL:
- readNull();
- break;
- case ENCODED_BOOLEAN:
- readBoolean();
- break;
- default:
- throw new DexException("Unexpected type: " + Integer.toHexString(type));
- }
- }
-
- private void checkType(int expected) {
- if (peek() != expected) {
- throw new IllegalStateException(
- String.format("Expected %x but was %x", expected, peek()));
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/FieldId.java b/dex/src/main/java/com/android/dex/FieldId.java
deleted file mode 100644
index 2f41708..0000000
--- a/dex/src/main/java/com/android/dex/FieldId.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class FieldId implements Comparable<FieldId> {
- private final Dex dex;
- private final int declaringClassIndex;
- private final int typeIndex;
- private final int nameIndex;
-
- public FieldId(Dex dex, int declaringClassIndex, int typeIndex, int nameIndex) {
- this.dex = dex;
- this.declaringClassIndex = declaringClassIndex;
- this.typeIndex = typeIndex;
- this.nameIndex = nameIndex;
- }
-
- public int getDeclaringClassIndex() {
- return declaringClassIndex;
- }
-
- public int getTypeIndex() {
- return typeIndex;
- }
-
- public int getNameIndex() {
- return nameIndex;
- }
-
- public int compareTo(FieldId other) {
- if (declaringClassIndex != other.declaringClassIndex) {
- return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);
- }
- if (nameIndex != other.nameIndex) {
- return Unsigned.compare(nameIndex, other.nameIndex);
- }
- return Unsigned.compare(typeIndex, other.typeIndex); // should always be 0
- }
-
- public void writeTo(Dex.Section out) {
- out.writeUnsignedShort(declaringClassIndex);
- out.writeUnsignedShort(typeIndex);
- out.writeInt(nameIndex);
- }
-
- @Override public String toString() {
- if (dex == null) {
- return declaringClassIndex + " " + typeIndex + " " + nameIndex;
- }
- return dex.typeNames().get(typeIndex) + "." + dex.strings().get(nameIndex);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/Leb128.java b/dex/src/main/java/com/android/dex/Leb128.java
deleted file mode 100644
index e4ca500..0000000
--- a/dex/src/main/java/com/android/dex/Leb128.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.ByteInput;
-import com.android.dex.util.ByteOutput;
-
-/**
- * Reads and writes DWARFv3 LEB 128 signed and unsigned integers. See DWARF v3
- * section 7.6.
- */
-public final class Leb128 {
- private Leb128() {
- }
-
- /**
- * Gets the number of bytes in the unsigned LEB128 encoding of the
- * given value.
- *
- * @param value the value in question
- * @return its write size, in bytes
- */
- public static int unsignedLeb128Size(int value) {
- // TODO: This could be much cleverer.
-
- int remaining = value >> 7;
- int count = 0;
-
- while (remaining != 0) {
- remaining >>= 7;
- count++;
- }
-
- return count + 1;
- }
-
- /**
- * Reads an signed integer from {@code in}.
- */
- public static int readSignedLeb128(ByteInput in) {
- int result = 0;
- int cur;
- int count = 0;
- int signBits = -1;
-
- do {
- cur = in.readByte() & 0xff;
- result |= (cur & 0x7f) << (count * 7);
- signBits <<= 7;
- count++;
- } while (((cur & 0x80) == 0x80) && count < 5);
-
- if ((cur & 0x80) == 0x80) {
- throw new DexException("invalid LEB128 sequence");
- }
-
- // Sign extend if appropriate
- if (((signBits >> 1) & result) != 0 ) {
- result |= signBits;
- }
-
- return result;
- }
-
- /**
- * Reads an unsigned integer from {@code in}.
- */
- public static int readUnsignedLeb128(ByteInput in) {
- int result = 0;
- int cur;
- int count = 0;
-
- do {
- cur = in.readByte() & 0xff;
- result |= (cur & 0x7f) << (count * 7);
- count++;
- } while (((cur & 0x80) == 0x80) && count < 5);
-
- if ((cur & 0x80) == 0x80) {
- throw new DexException("invalid LEB128 sequence");
- }
-
- return result;
- }
-
- /**
- * Writes {@code value} as an unsigned integer to {@code out}, starting at
- * {@code offset}. Returns the number of bytes written.
- */
- public static void writeUnsignedLeb128(ByteOutput out, int value) {
- int remaining = value >>> 7;
-
- while (remaining != 0) {
- out.writeByte((byte) ((value & 0x7f) | 0x80));
- value = remaining;
- remaining >>>= 7;
- }
-
- out.writeByte((byte) (value & 0x7f));
- }
-
- /**
- * Writes {@code value} as a signed integer to {@code out}, starting at
- * {@code offset}. Returns the number of bytes written.
- */
- public static void writeSignedLeb128(ByteOutput out, int value) {
- int remaining = value >> 7;
- boolean hasMore = true;
- int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
-
- while (hasMore) {
- hasMore = (remaining != end)
- || ((remaining & 1) != ((value >> 6) & 1));
-
- out.writeByte((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0)));
- value = remaining;
- remaining >>= 7;
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/MethodId.java b/dex/src/main/java/com/android/dex/MethodId.java
deleted file mode 100644
index e518740..0000000
--- a/dex/src/main/java/com/android/dex/MethodId.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class MethodId implements Comparable<MethodId> {
- private final Dex dex;
- private final int declaringClassIndex;
- private final int protoIndex;
- private final int nameIndex;
-
- public MethodId(Dex dex, int declaringClassIndex, int protoIndex, int nameIndex) {
- this.dex = dex;
- this.declaringClassIndex = declaringClassIndex;
- this.protoIndex = protoIndex;
- this.nameIndex = nameIndex;
- }
-
- public int getDeclaringClassIndex() {
- return declaringClassIndex;
- }
-
- public int getProtoIndex() {
- return protoIndex;
- }
-
- public int getNameIndex() {
- return nameIndex;
- }
-
- public int compareTo(MethodId other) {
- if (declaringClassIndex != other.declaringClassIndex) {
- return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);
- }
- if (nameIndex != other.nameIndex) {
- return Unsigned.compare(nameIndex, other.nameIndex);
- }
- return Unsigned.compare(protoIndex, other.protoIndex);
- }
-
- public void writeTo(Dex.Section out) {
- out.writeUnsignedShort(declaringClassIndex);
- out.writeUnsignedShort(protoIndex);
- out.writeInt(nameIndex);
- }
-
- @Override public String toString() {
- if (dex == null) {
- return declaringClassIndex + " " + protoIndex + " " + nameIndex;
- }
- return dex.typeNames().get(declaringClassIndex)
- + "." + dex.strings().get(nameIndex)
- + dex.readTypeList(dex.protoIds().get(protoIndex).getParametersOffset());
- }
-}
diff --git a/dex/src/main/java/com/android/dex/Mutf8.java b/dex/src/main/java/com/android/dex/Mutf8.java
deleted file mode 100644
index c64da33..0000000
--- a/dex/src/main/java/com/android/dex/Mutf8.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.ByteInput;
-import java.io.UTFDataFormatException;
-
-/**
- * Modified UTF-8 as described in the dex file format spec.
- *
- * <p>Derived from libcore's MUTF-8 encoder at java.nio.charset.ModifiedUtf8.
- */
-public final class Mutf8 {
- private Mutf8() {}
-
- /**
- * Decodes bytes from {@code in} into {@code out} until a delimiter 0x00 is
- * encountered. Returns a new string containing the decoded characters.
- */
- public static String decode(ByteInput in, char[] out) throws UTFDataFormatException {
- int s = 0;
- while (true) {
- char a = (char) (in.readByte() & 0xff);
- if (a == 0) {
- return new String(out, 0, s);
- }
- out[s] = a;
- if (a < '\u0080') {
- s++;
- } else if ((a & 0xe0) == 0xc0) {
- int b = in.readByte() & 0xff;
- if ((b & 0xC0) != 0x80) {
- throw new UTFDataFormatException("bad second byte");
- }
- out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
- } else if ((a & 0xf0) == 0xe0) {
- int b = in.readByte() & 0xff;
- int c = in.readByte() & 0xff;
- if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {
- throw new UTFDataFormatException("bad second or third byte");
- }
- out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));
- } else {
- throw new UTFDataFormatException("bad byte");
- }
- }
- }
-
- /**
- * Returns the number of bytes the modified UTF8 representation of 's' would take.
- */
- private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {
- long result = 0;
- final int length = s.length();
- for (int i = 0; i < length; ++i) {
- char ch = s.charAt(i);
- if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
- ++result;
- } else if (ch <= 2047) {
- result += 2;
- } else {
- result += 3;
- }
- if (shortLength && result > 65535) {
- throw new UTFDataFormatException("String more than 65535 UTF bytes long");
- }
- }
- return result;
- }
-
- /**
- * Encodes the modified UTF-8 bytes corresponding to {@code s} into {@code
- * dst}, starting at {@code offset}.
- */
- public static void encode(byte[] dst, int offset, String s) {
- final int length = s.length();
- for (int i = 0; i < length; i++) {
- char ch = s.charAt(i);
- if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
- dst[offset++] = (byte) ch;
- } else if (ch <= 2047) {
- dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));
- dst[offset++] = (byte) (0x80 | (0x3f & ch));
- } else {
- dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12)));
- dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6)));
- dst[offset++] = (byte) (0x80 | (0x3f & ch));
- }
- }
- }
-
- /**
- * Returns an array containing the <i>modified UTF-8</i> form of {@code s}.
- */
- public static byte[] encode(String s) throws UTFDataFormatException {
- int utfCount = (int) countBytes(s, true);
- byte[] result = new byte[utfCount];
- encode(result, 0, s);
- return result;
- }
-}
diff --git a/dex/src/main/java/com/android/dex/ProtoId.java b/dex/src/main/java/com/android/dex/ProtoId.java
deleted file mode 100644
index 9d9f484..0000000
--- a/dex/src/main/java/com/android/dex/ProtoId.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class ProtoId implements Comparable<ProtoId> {
- private final Dex dex;
- private final int shortyIndex;
- private final int returnTypeIndex;
- private final int parametersOffset;
-
- public ProtoId(Dex dex, int shortyIndex, int returnTypeIndex, int parametersOffset) {
- this.dex = dex;
- this.shortyIndex = shortyIndex;
- this.returnTypeIndex = returnTypeIndex;
- this.parametersOffset = parametersOffset;
- }
-
- public int compareTo(ProtoId other) {
- if (returnTypeIndex != other.returnTypeIndex) {
- return Unsigned.compare(returnTypeIndex, other.returnTypeIndex);
- }
- return Unsigned.compare(parametersOffset, other.parametersOffset);
- }
-
- public int getShortyIndex() {
- return shortyIndex;
- }
-
- public int getReturnTypeIndex() {
- return returnTypeIndex;
- }
-
- public int getParametersOffset() {
- return parametersOffset;
- }
-
- public void writeTo(Dex.Section out) {
- out.writeInt(shortyIndex);
- out.writeInt(returnTypeIndex);
- out.writeInt(parametersOffset);
- }
-
- @Override public String toString() {
- if (dex == null) {
- return shortyIndex + " " + returnTypeIndex + " " + parametersOffset;
- }
-
- return dex.strings().get(shortyIndex)
- + ": " + dex.typeNames().get(returnTypeIndex)
- + " " + dex.readTypeList(parametersOffset);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/SizeOf.java b/dex/src/main/java/com/android/dex/SizeOf.java
deleted file mode 100644
index 65fab56..0000000
--- a/dex/src/main/java/com/android/dex/SizeOf.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-public final class SizeOf {
- private SizeOf() {}
-
- public static final int UBYTE = 1;
- public static final int USHORT = 2;
- public static final int UINT = 4;
-
- public static final int SIGNATURE = UBYTE * 20;
-
- /**
- * magic ubyte[8]
- * checksum uint
- * signature ubyte[20]
- * file_size uint
- * header_size uint
- * endian_tag uint
- * link_size uint
- * link_off uint
- * map_off uint
- * string_ids_size uint
- * string_ids_off uint
- * type_ids_size uint
- * type_ids_off uint
- * proto_ids_size uint
- * proto_ids_off uint
- * field_ids_size uint
- * field_ids_off uint
- * method_ids_size uint
- * method_ids_off uint
- * class_defs_size uint
- * class_defs_off uint
- * data_size uint
- * data_off uint
- */
- public static final int HEADER_ITEM = (8 * UBYTE) + UINT + SIGNATURE + (20 * UINT); // 0x70
-
- /**
- * string_data_off uint
- */
- public static final int STRING_ID_ITEM = UINT;
-
- /**
- * descriptor_idx uint
- */
- public static final int TYPE_ID_ITEM = UINT;
-
- /**
- * type_idx ushort
- */
- public static final int TYPE_ITEM = USHORT;
-
- /**
- * shorty_idx uint
- * return_type_idx uint
- * return_type_idx uint
- */
- public static final int PROTO_ID_ITEM = UINT + UINT + UINT;
-
- /**
- * class_idx ushort
- * type_idx/proto_idx ushort
- * name_idx uint
- */
- public static final int MEMBER_ID_ITEM = USHORT + USHORT + UINT;
-
- /**
- * class_idx uint
- * access_flags uint
- * superclass_idx uint
- * interfaces_off uint
- * source_file_idx uint
- * annotations_off uint
- * class_data_off uint
- * static_values_off uint
- */
- public static final int CLASS_DEF_ITEM = 8 * UINT;
-
- /**
- * type ushort
- * unused ushort
- * size uint
- * offset uint
- */
- public static final int MAP_ITEM = USHORT + USHORT + UINT + UINT;
-
- /**
- * start_addr uint
- * insn_count ushort
- * handler_off ushort
- */
- public static final int TRY_ITEM = UINT + USHORT + USHORT;
-}
diff --git a/dex/src/main/java/com/android/dex/TableOfContents.java b/dex/src/main/java/com/android/dex/TableOfContents.java
deleted file mode 100644
index b33a749..0000000
--- a/dex/src/main/java/com/android/dex/TableOfContents.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-
-/**
- * The file header and map.
- */
-public final class TableOfContents {
-
- /*
- * TODO: factor out ID constants.
- */
-
- public final Section header = new Section(0x0000);
- public final Section stringIds = new Section(0x0001);
- public final Section typeIds = new Section(0x0002);
- public final Section protoIds = new Section(0x0003);
- public final Section fieldIds = new Section(0x0004);
- public final Section methodIds = new Section(0x0005);
- public final Section classDefs = new Section(0x0006);
- public final Section callSiteIds = new Section(0x0007);
- public final Section methodHandles = new Section(0x0008);
- public final Section mapList = new Section(0x1000);
- public final Section typeLists = new Section(0x1001);
- public final Section annotationSetRefLists = new Section(0x1002);
- public final Section annotationSets = new Section(0x1003);
- public final Section classDatas = new Section(0x2000);
- public final Section codes = new Section(0x2001);
- public final Section stringDatas = new Section(0x2002);
- public final Section debugInfos = new Section(0x2003);
- public final Section annotations = new Section(0x2004);
- public final Section encodedArrays = new Section(0x2005);
- public final Section annotationsDirectories = new Section(0x2006);
- public final Section[] sections = {
- header, stringIds, typeIds, protoIds, fieldIds, methodIds, classDefs, mapList, callSiteIds,
- methodHandles, typeLists, annotationSetRefLists, annotationSets, classDatas, codes,
- stringDatas, debugInfos, annotations, encodedArrays, annotationsDirectories
- };
-
- public int apiLevel;
- public int checksum;
- public byte[] signature;
- public int fileSize;
- public int linkSize;
- public int linkOff;
- public int dataSize;
- public int dataOff;
-
- public TableOfContents() {
- signature = new byte[20];
- }
-
- public void readFrom(Dex dex) throws IOException {
- readHeader(dex.open(0));
- readMap(dex.open(mapList.off));
- computeSizesFromOffsets();
- }
-
- private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException {
- byte[] magic = headerIn.readByteArray(8);
-
- if (!DexFormat.isSupportedDexMagic(magic)) {
- String msg =
- String.format("Unexpected magic: [0x%02x, 0x%02x, 0x%02x, 0x%02x, "
- + "0x%02x, 0x%02x, 0x%02x, 0x%02x]",
- magic[0], magic[1], magic[2], magic[3],
- magic[4], magic[5], magic[6], magic[7]);
- throw new DexException(msg);
- }
-
- apiLevel = DexFormat.magicToApi(magic);
- checksum = headerIn.readInt();
- signature = headerIn.readByteArray(20);
- fileSize = headerIn.readInt();
- int headerSize = headerIn.readInt();
- if (headerSize != SizeOf.HEADER_ITEM) {
- throw new DexException("Unexpected header: 0x" + Integer.toHexString(headerSize));
- }
- int endianTag = headerIn.readInt();
- if (endianTag != DexFormat.ENDIAN_TAG) {
- throw new DexException("Unexpected endian tag: 0x" + Integer.toHexString(endianTag));
- }
- linkSize = headerIn.readInt();
- linkOff = headerIn.readInt();
- mapList.off = headerIn.readInt();
- if (mapList.off == 0) {
- throw new DexException("Cannot merge dex files that do not contain a map");
- }
- stringIds.size = headerIn.readInt();
- stringIds.off = headerIn.readInt();
- typeIds.size = headerIn.readInt();
- typeIds.off = headerIn.readInt();
- protoIds.size = headerIn.readInt();
- protoIds.off = headerIn.readInt();
- fieldIds.size = headerIn.readInt();
- fieldIds.off = headerIn.readInt();
- methodIds.size = headerIn.readInt();
- methodIds.off = headerIn.readInt();
- classDefs.size = headerIn.readInt();
- classDefs.off = headerIn.readInt();
- dataSize = headerIn.readInt();
- dataOff = headerIn.readInt();
- }
-
- private void readMap(Dex.Section in) throws IOException {
- int mapSize = in.readInt();
- Section previous = null;
- for (int i = 0; i < mapSize; i++) {
- short type = in.readShort();
- in.readShort(); // unused
- Section section = getSection(type);
- int size = in.readInt();
- int offset = in.readInt();
-
- if ((section.size != 0 && section.size != size)
- || (section.off != -1 && section.off != offset)) {
- throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type));
- }
-
- section.size = size;
- section.off = offset;
-
- if (previous != null && previous.off > section.off) {
- throw new DexException("Map is unsorted at " + previous + ", " + section);
- }
-
- previous = section;
- }
- Arrays.sort(sections);
- }
-
- public void computeSizesFromOffsets() {
- int end = dataOff + dataSize;
- for (int i = sections.length - 1; i >= 0; i--) {
- Section section = sections[i];
- if (section.off == -1) {
- continue;
- }
- if (section.off > end) {
- throw new DexException("Map is unsorted at " + section);
- }
- section.byteCount = end - section.off;
- end = section.off;
- }
- }
-
- private Section getSection(short type) {
- for (Section section : sections) {
- if (section.type == type) {
- return section;
- }
- }
- throw new IllegalArgumentException("No such map item: " + type);
- }
-
- public void writeHeader(Dex.Section out, int api) throws IOException {
- out.write(DexFormat.apiToMagic(api).getBytes("UTF-8"));
- out.writeInt(checksum);
- out.write(signature);
- out.writeInt(fileSize);
- out.writeInt(SizeOf.HEADER_ITEM);
- out.writeInt(DexFormat.ENDIAN_TAG);
- out.writeInt(linkSize);
- out.writeInt(linkOff);
- out.writeInt(mapList.off);
- out.writeInt(stringIds.size);
- out.writeInt(stringIds.off);
- out.writeInt(typeIds.size);
- out.writeInt(typeIds.off);
- out.writeInt(protoIds.size);
- out.writeInt(protoIds.off);
- out.writeInt(fieldIds.size);
- out.writeInt(fieldIds.off);
- out.writeInt(methodIds.size);
- out.writeInt(methodIds.off);
- out.writeInt(classDefs.size);
- out.writeInt(classDefs.off);
- out.writeInt(dataSize);
- out.writeInt(dataOff);
- }
-
- public void writeMap(Dex.Section out) throws IOException {
- int count = 0;
- for (Section section : sections) {
- if (section.exists()) {
- count++;
- }
- }
-
- out.writeInt(count);
- for (Section section : sections) {
- if (section.exists()) {
- out.writeShort(section.type);
- out.writeShort((short) 0);
- out.writeInt(section.size);
- out.writeInt(section.off);
- }
- }
- }
-
- public static class Section implements Comparable<Section> {
- public final short type;
- public int size = 0;
- public int off = -1;
- public int byteCount = 0;
-
- public Section(int type) {
- this.type = (short) type;
- }
-
- public boolean exists() {
- return size > 0;
- }
-
- public int compareTo(Section section) {
- if (off != section.off) {
- return off < section.off ? -1 : 1;
- }
- return 0;
- }
-
- @Override public String toString() {
- return String.format("Section[type=%#x,off=%#x,size=%#x]", type, off, size);
- }
- }
-}
diff --git a/dex/src/main/java/com/android/dex/TypeList.java b/dex/src/main/java/com/android/dex/TypeList.java
deleted file mode 100644
index 123e82c..0000000
--- a/dex/src/main/java/com/android/dex/TypeList.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class TypeList implements Comparable<TypeList> {
-
- public static final TypeList EMPTY = new TypeList(null, Dex.EMPTY_SHORT_ARRAY);
-
- private final Dex dex;
- private final short[] types;
-
- public TypeList(Dex dex, short[] types) {
- this.dex = dex;
- this.types = types;
- }
-
- public short[] getTypes() {
- return types;
- }
-
- @Override public int compareTo(TypeList other) {
- for (int i = 0; i < types.length && i < other.types.length; i++) {
- if (types[i] != other.types[i]) {
- return Unsigned.compare(types[i], other.types[i]);
- }
- }
- return Unsigned.compare(types.length, other.types.length);
- }
-
- @Override public String toString() {
- StringBuilder result = new StringBuilder();
- result.append("(");
- for (int i = 0, typesLength = types.length; i < typesLength; i++) {
- result.append(dex != null ? dex.typeNames().get(types[i]) : types[i]);
- }
- result.append(")");
- return result.toString();
- }
-}
diff --git a/dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java b/dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java
deleted file mode 100644
index 889a936..0000000
--- a/dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex.util;
-
-public final class ByteArrayByteInput implements ByteInput {
-
- private final byte[] bytes;
- private int position;
-
- public ByteArrayByteInput(byte... bytes) {
- this.bytes = bytes;
- }
-
- @Override public byte readByte() {
- return bytes[position++];
- }
-}
diff --git a/dex/src/main/java/com/android/dex/util/ByteInput.java b/dex/src/main/java/com/android/dex/util/ByteInput.java
deleted file mode 100644
index f1a7196..0000000
--- a/dex/src/main/java/com/android/dex/util/ByteInput.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex.util;
-
-/**
- * A byte source.
- */
-public interface ByteInput {
-
- /**
- * Returns a byte.
- *
- * @throws IndexOutOfBoundsException if all bytes have been read.
- */
- byte readByte();
-}
diff --git a/dex/src/main/java/com/android/dex/util/ByteOutput.java b/dex/src/main/java/com/android/dex/util/ByteOutput.java
deleted file mode 100644
index eb77040..0000000
--- a/dex/src/main/java/com/android/dex/util/ByteOutput.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex.util;
-
-/**
- * A byte sink.
- */
-public interface ByteOutput {
-
- /**
- * Writes a byte.
- *
- * @throws IndexOutOfBoundsException if all bytes have been written.
- */
- void writeByte(int i);
-}
diff --git a/dex/src/main/java/com/android/dex/util/ExceptionWithContext.java b/dex/src/main/java/com/android/dex/util/ExceptionWithContext.java
deleted file mode 100644
index 5dfd954..0000000
--- a/dex/src/main/java/com/android/dex/util/ExceptionWithContext.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed 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 com.android.dex.util;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-/**
- * Exception which carries around structured context.
- */
-public class ExceptionWithContext extends RuntimeException {
- /** {@code non-null;} human-oriented context of the exception */
- private StringBuffer context;
-
- /**
- * Augments the given exception with the given context, and return the
- * result. The result is either the given exception if it was an
- * {@link ExceptionWithContext}, or a newly-constructed exception if it
- * was not.
- *
- * @param ex {@code non-null;} the exception to augment
- * @param str {@code non-null;} context to add
- * @return {@code non-null;} an appropriate instance
- */
- public static ExceptionWithContext withContext(Throwable ex, String str) {
- ExceptionWithContext ewc;
-
- if (ex instanceof ExceptionWithContext) {
- ewc = (ExceptionWithContext) ex;
- } else {
- ewc = new ExceptionWithContext(ex);
- }
-
- ewc.addContext(str);
- return ewc;
- }
-
- /**
- * Constructs an instance.
- *
- * @param message human-oriented message
- */
- public ExceptionWithContext(String message) {
- this(message, null);
- }
-
- /**
- * Constructs an instance.
- *
- * @param cause {@code null-ok;} exception that caused this one
- */
- public ExceptionWithContext(Throwable cause) {
- this(null, cause);
- }
-
- /**
- * Constructs an instance.
- *
- * @param message human-oriented message
- * @param cause {@code null-ok;} exception that caused this one
- */
- public ExceptionWithContext(String message, Throwable cause) {
- super((message != null) ? message :
- (cause != null) ? cause.getMessage() : null,
- cause);
-
- if (cause instanceof ExceptionWithContext) {
- String ctx = ((ExceptionWithContext) cause).context.toString();
- context = new StringBuffer(ctx.length() + 200);
- context.append(ctx);
- } else {
- context = new StringBuffer(200);
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public void printStackTrace(PrintStream out) {
- super.printStackTrace(out);
- out.println(context);
- }
-
- /** {@inheritDoc} */
- @Override
- public void printStackTrace(PrintWriter out) {
- super.printStackTrace(out);
- out.println(context);
- }
-
- /**
- * Adds a line of context to this instance.
- *
- * @param str {@code non-null;} new context
- */
- public void addContext(String str) {
- if (str == null) {
- throw new NullPointerException("str == null");
- }
-
- context.append(str);
- if (!str.endsWith("\n")) {
- context.append('\n');
- }
- }
-
- /**
- * Gets the context.
- *
- * @return {@code non-null;} the context
- */
- public String getContext() {
- return context.toString();
- }
-
- /**
- * Prints the message and context.
- *
- * @param out {@code non-null;} where to print to
- */
- public void printContext(PrintStream out) {
- out.println(getMessage());
- out.print(context);
- }
-
- /**
- * Prints the message and context.
- *
- * @param out {@code non-null;} where to print to
- */
- public void printContext(PrintWriter out) {
- out.println(getMessage());
- out.print(context);
- }
-}
diff --git a/dex/src/main/java/com/android/dex/util/FileUtils.java b/dex/src/main/java/com/android/dex/util/FileUtils.java
deleted file mode 100644
index 4cea95c..0000000
--- a/dex/src/main/java/com/android/dex/util/FileUtils.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed 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 com.android.dex.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-/**
- * File I/O utilities.
- */
-public final class FileUtils {
- private FileUtils() {
- }
-
- /**
- * Reads the named file, translating {@link IOException} to a
- * {@link RuntimeException} of some sort.
- *
- * @param fileName {@code non-null;} name of the file to read
- * @return {@code non-null;} contents of the file
- */
- public static byte[] readFile(String fileName) {
- File file = new File(fileName);
- return readFile(file);
- }
-
- /**
- * Reads the given file, translating {@link IOException} to a
- * {@link RuntimeException} of some sort.
- *
- * @param file {@code non-null;} the file to read
- * @return {@code non-null;} contents of the file
- */
- public static byte[] readFile(File file) {
- if (!file.exists()) {
- throw new RuntimeException(file + ": file not found");
- }
-
- if (!file.isFile()) {
- throw new RuntimeException(file + ": not a file");
- }
-
- if (!file.canRead()) {
- throw new RuntimeException(file + ": file not readable");
- }
-
- long longLength = file.length();
- int length = (int) longLength;
- if (length != longLength) {
- throw new RuntimeException(file + ": file too long");
- }
-
- byte[] result = new byte[length];
-
- try {
- FileInputStream in = new FileInputStream(file);
- int at = 0;
- while (length > 0) {
- int amt = in.read(result, at, length);
- if (amt == -1) {
- throw new RuntimeException(file + ": unexpected EOF");
- }
- at += amt;
- length -= amt;
- }
- in.close();
- } catch (IOException ex) {
- throw new RuntimeException(file + ": trouble reading", ex);
- }
-
- return result;
- }
-
- /**
- * Returns true if {@code fileName} names a .zip, .jar, or .apk.
- */
- public static boolean hasArchiveSuffix(String fileName) {
- return fileName.endsWith(".zip")
- || fileName.endsWith(".jar")
- || fileName.endsWith(".apk");
- }
-}
diff --git a/dex/src/main/java/com/android/dex/util/Unsigned.java b/dex/src/main/java/com/android/dex/util/Unsigned.java
deleted file mode 100644
index cb50d0a..0000000
--- a/dex/src/main/java/com/android/dex/util/Unsigned.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex.util;
-
-/**
- * Unsigned arithmetic over Java's signed types.
- */
-public final class Unsigned {
- private Unsigned() {}
-
- public static int compare(short ushortA, short ushortB) {
- if (ushortA == ushortB) {
- return 0;
- }
- int a = ushortA & 0xFFFF;
- int b = ushortB & 0xFFFF;
- return a < b ? -1 : 1;
- }
-
- public static int compare(int uintA, int uintB) {
- if (uintA == uintB) {
- return 0;
- }
- long a = uintA & 0xFFFFFFFFL;
- long b = uintB & 0xFFFFFFFFL;
- return a < b ? -1 : 1;
- }
-}
diff --git a/dex/src/test/java/com/android/dex/EncodedValueReaderTest.java b/dex/src/test/java/com/android/dex/EncodedValueReaderTest.java
deleted file mode 100644
index a4ca376..0000000
--- a/dex/src/test/java/com/android/dex/EncodedValueReaderTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed 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 com.android.dex;
-
-import com.android.dex.util.ByteArrayByteInput;
-import junit.framework.TestCase;
-
-public final class EncodedValueReaderTest extends TestCase {
-
- public void testReadByte() {
- assertEquals((byte) 0x80, readerOf(0, 0x80).readByte());
- assertEquals((byte) 0xff, readerOf(0, 0xff).readByte());
- assertEquals((byte) 0x00, readerOf(0, 0x00).readByte());
- assertEquals((byte) 0x01, readerOf(0, 0x01).readByte());
- assertEquals((byte) 0x7f, readerOf(0, 0x7f).readByte());
- }
-
- public void testReadShort() {
- assertEquals((short) 0x8000, readerOf(34, 0x00, 0x80).readShort());
- assertEquals((short) 0, readerOf( 2, 0x00).readShort());
- assertEquals((short) 0xab, readerOf(34, 0xab, 0x00).readShort());
- assertEquals((short) 0xabcd, readerOf(34, 0xcd, 0xab).readShort());
- assertEquals((short) 0x7FFF, readerOf(34, 0xff, 0x7f).readShort());
- }
-
- public void testReadInt() {
- assertEquals(0x80000000, readerOf(100, 0x00, 0x00, 0x00, 0x80).readInt());
- assertEquals( 0x00, readerOf( 4, 0x00).readInt());
- assertEquals( 0xab, readerOf( 36, 0xab, 0x00).readInt());
- assertEquals( 0xabcd, readerOf( 68, 0xcd, 0xab, 0x00).readInt());
- assertEquals( 0xabcdef, readerOf(100, 0xef, 0xcd, 0xab, 0x00).readInt());
- assertEquals(0xabcdef01, readerOf(100, 0x01, 0xef, 0xcd, 0xab).readInt());
- assertEquals(0x7fffffff, readerOf(100, 0xff, 0xff, 0xff, 127).readInt());
- }
-
- public void testReadLong() {
- assertEquals(0x8000000000000000L, readerOf( -26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80).readLong());
- assertEquals( 0x00L, readerOf( 6, 0x00).readLong());
- assertEquals( 0xabL, readerOf( 38, 0xab, 0x00).readLong());
- assertEquals( 0xabcdL, readerOf( 70, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdefL, readerOf( 102, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdef01L, readerOf(-122, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdef0123L, readerOf( -90, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdef012345L, readerOf( -58, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals( 0xabcdef01234567L, readerOf( -26, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
- assertEquals(0xabcdef0123456789L, readerOf( -26, 0x89, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab).readLong());
- assertEquals(0x7fffffffffffffffL, readerOf( -26, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f).readLong());
- }
-
- public void testReadFloat() {
- assertEquals(Float.NEGATIVE_INFINITY, readerOf(48, -128, -1).readFloat());
- assertEquals(Float.POSITIVE_INFINITY, readerOf(48, -128, 127).readFloat());
- assertEquals(Float.NaN, readerOf(48, -64, 127).readFloat());
- assertEquals(-0.0f, readerOf(16, -128).readFloat());
- assertEquals(0.0f, readerOf(16, 0).readFloat());
- assertEquals(0.5f, readerOf(16, 63).readFloat());
- assertEquals(1f, readerOf(48, -128, 63).readFloat());
- assertEquals(1.0E06f, readerOf(80, 36, 116, 73).readFloat());
- assertEquals(1.0E12f, readerOf(112, -91, -44, 104, 83).readFloat());
- }
-
- public void testReadDouble() {
- assertEquals(Double.NEGATIVE_INFINITY, readerOf(49, -16, -1).readDouble());
- assertEquals(Double.POSITIVE_INFINITY, readerOf(49, -16, 127).readDouble());
- assertEquals(Double.NaN, readerOf(49, -8, 127).readDouble());
- assertEquals(-0.0, readerOf(17, -128).readDouble());
- assertEquals(0.0, readerOf(17, 0).readDouble());
- assertEquals(0.5, readerOf(49, -32, 63).readDouble());
- assertEquals(1.0, readerOf(49, -16, 63).readDouble());
- assertEquals(1.0E06, readerOf(113, -128, -124, 46, 65).readDouble());
- assertEquals(1.0E12, readerOf(-111, -94, -108, 26, 109, 66).readDouble());
- assertEquals(1.0E24, readerOf(-15, -76, -99, -39, 121, 67, 120, -22, 68).readDouble());
- }
-
- public void testReadChar() {
- assertEquals('\u0000', readerOf( 3, 0x00).readChar());
- assertEquals('\u00ab', readerOf( 3, 0xab).readChar());
- assertEquals('\uabcd', readerOf(35, 0xcd, 0xab).readChar());
- assertEquals('\uffff', readerOf(35, 0xff, 0xff).readChar());
- }
-
- public void testReadBoolean() {
- assertEquals(true, readerOf(63).readBoolean());
- assertEquals(false, readerOf(31).readBoolean());
- }
-
- public void testReadNull() {
- readerOf(30).readNull();
- }
-
- public void testReadReference() {
- assertEquals( 0xab, readerOf(0x17, 0xab).readString());
- assertEquals( 0xabcd, readerOf(0x37, 0xcd, 0xab).readString());
- assertEquals( 0xabcdef, readerOf(0x57, 0xef, 0xcd, 0xab).readString());
- assertEquals(0xabcdef01, readerOf(0x77, 0x01, 0xef, 0xcd, 0xab).readString());
- }
-
- public void testReadWrongType() {
- try {
- readerOf(0x17, 0xab).readField();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- private EncodedValueReader readerOf(int... bytes) {
- byte[] data = new byte[bytes.length];
- for (int i = 0; i < bytes.length; i++) {
- data[i] = (byte) bytes[i];
- }
- return new EncodedValueReader(new ByteArrayByteInput(data));
- }
-}
diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java
index 1f90d13..864196d 100644
--- a/libart/src/main/java/java/lang/DexCache.java
+++ b/libart/src/main/java/java/lang/DexCache.java
@@ -33,7 +33,6 @@
package java.lang;
import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
/**
* A dex cache holds resolved copies of strings, fields, methods, and classes from the dexfile.
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index cae8083..7db7f75 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -63,6 +63,25 @@
/** @hide */ public static void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.bind(fd, address); }
/**
+ * See <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
+ *
+ * @hide
+ */
+ public static StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException {
+ return Libcore.os.capget(hdr);
+ }
+
+ /**
+ * See <a href="http://man7.org/linux/man-pages/man2/capset.2.html">capset(2)</a>.
+ *
+ * @hide
+ */
+ public static void capset(StructCapUserHeader hdr, StructCapUserData[] data)
+ throws ErrnoException {
+ Libcore.os.capset(hdr, data);
+ }
+
+ /**
* See <a href="http://man7.org/linux/man-pages/man2/chmod.2.html">chmod(2)</a>.
*/
public static void chmod(String path, int mode) throws ErrnoException { Libcore.os.chmod(path, mode); }
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 10ea52f..adad301 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -24,6 +24,20 @@
}
/**
+ * Returns the index of the element in the cap_user_data array that this capability is stored
+ * in.
+ * @hide
+ */
+ public static int CAP_TO_INDEX(int x) { return x >>> 5; }
+
+ /**
+ * Returns the mask for the given capability. This is relative to the capability's cap_user_data
+ * element, the index of which can be retrieved with CAP_TO_INDEX.
+ * @hide
+ */
+ public static int CAP_TO_MASK(int x) { return 1 << (x & 31); }
+
+ /**
* Tests whether the given mode is a block device.
*/
public static boolean S_ISBLK(int mode) { return (mode & S_IFMT) == S_IFBLK; }
@@ -320,6 +334,7 @@
/** @hide */ public static final int IP_RECVTOS = placeholder();
public static final int IP_TOS = placeholder();
public static final int IP_TTL = placeholder();
+ /** @hide */ public static final int _LINUX_CAPABILITY_VERSION_3 = placeholder();
public static final int MAP_FIXED = placeholder();
/** @hide */ public static final int MAP_POPULATE = placeholder();
public static final int MAP_PRIVATE = placeholder();
@@ -372,6 +387,8 @@
public static final int POLLRDNORM = placeholder();
public static final int POLLWRBAND = placeholder();
public static final int POLLWRNORM = placeholder();
+ /** @hide */ public static final int PR_CAP_AMBIENT = placeholder();
+ /** @hide */ public static final int PR_CAP_AMBIENT_RAISE = placeholder();
public static final int PR_GET_DUMPABLE = placeholder();
public static final int PR_SET_DUMPABLE = placeholder();
public static final int PR_SET_NO_NEW_PRIVS = placeholder();
diff --git a/luni/src/main/java/android/system/StructCapUserData.java b/luni/src/main/java/android/system/StructCapUserData.java
new file mode 100644
index 0000000..af63caf
--- /dev/null
+++ b/luni/src/main/java/android/system/StructCapUserData.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed 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 android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Corresponds to Linux' __user_cap_data_struct for capget and capset.
+ *
+ * @hide
+ */
+public final class StructCapUserData {
+ /** Effective capability mask. */
+ public final int effective; /* __u32 */
+
+ /** Permitted capability mask. */
+ public final int permitted; /* __u32 */
+
+ /** Inheritable capability mask. */
+ public final int inheritable; /* __u32 */
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructCapUserData(int effective, int permitted, int inheritable) {
+ this.effective = effective;
+ this.permitted = permitted;
+ this.inheritable = inheritable;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/android/system/StructCapUserHeader.java b/luni/src/main/java/android/system/StructCapUserHeader.java
new file mode 100644
index 0000000..abbb395
--- /dev/null
+++ b/luni/src/main/java/android/system/StructCapUserHeader.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed 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 android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Corresponds to Linux' __user_cap_header_struct for capget and capset.
+ *
+ * @hide
+ */
+public final class StructCapUserHeader {
+ /**
+ * Version of the header. Note this is not final as capget() may mutate the field when an
+ * invalid version is provided. See
+ * <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
+ */
+ public int version; /* __u32 */
+
+ /** Pid of the header. The pid a call applies to. */
+ public final int pid;
+
+ /**
+ * Constructs an instance with the given field values.
+ */
+ public StructCapUserHeader(int version, int pid) {
+ this.version = version;
+ this.pid = pid;
+ }
+
+ @Override public String toString() {
+ return Objects.toString(this);
+ }
+}
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index ac805e8..55d4d82 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -19,6 +19,8 @@
import android.system.ErrnoException;
import android.system.GaiException;
import android.system.StructAddrinfo;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
import android.system.StructFlock;
import android.system.StructGroupReq;
import android.system.StructGroupSourceReq;
@@ -56,6 +58,14 @@
public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return os.android_getaddrinfo(node, hints, netId); }
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.bind(fd, address, port); }
public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { os.bind(fd, address); }
+ @Override
+ public StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException {
+ return os.capget(hdr);
+ }
+ @Override
+ public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException {
+ os.capset(hdr, data);
+ }
public void chmod(String path, int mode) throws ErrnoException { os.chmod(path, mode); }
public void chown(String path, int uid, int gid) throws ErrnoException { os.chown(path, uid, gid); }
public void close(FileDescriptor fd) throws ErrnoException { os.close(fd); }
diff --git a/luni/src/main/java/libcore/io/Linux.java b/luni/src/main/java/libcore/io/Linux.java
index cbd7b25..09adb09 100644
--- a/luni/src/main/java/libcore/io/Linux.java
+++ b/luni/src/main/java/libcore/io/Linux.java
@@ -19,6 +19,8 @@
import android.system.ErrnoException;
import android.system.GaiException;
import android.system.StructAddrinfo;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
import android.system.StructFlock;
import android.system.StructGroupReq;
import android.system.StructGroupSourceReq;
@@ -50,6 +52,11 @@
public native InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public native void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
+ @Override
+ public native StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException;
+ @Override
+ public native void capset(StructCapUserHeader hdr, StructCapUserData[] data)
+ throws ErrnoException;
public native void chmod(String path, int mode) throws ErrnoException;
public native void chown(String path, int uid, int gid) throws ErrnoException;
public native void close(FileDescriptor fd) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 41b034b..20a84bd 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -19,6 +19,8 @@
import android.system.ErrnoException;
import android.system.GaiException;
import android.system.StructAddrinfo;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
import android.system.StructFlock;
import android.system.StructGroupReq;
import android.system.StructGroupSourceReq;
@@ -47,6 +49,8 @@
public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
+ public StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException;
+ public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException;
public void chmod(String path, int mode) throws ErrnoException;
public void chown(String path, int uid, int gid) throws ErrnoException;
public void close(FileDescriptor fd) throws ErrnoException;
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 3cb3ee9..3ae4af6 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -342,6 +342,9 @@
initConstant(env, c, "IP_RECVTOS", IP_RECVTOS);
initConstant(env, c, "IP_TOS", IP_TOS);
initConstant(env, c, "IP_TTL", IP_TTL);
+#if defined(_LINUX_CAPABILITY_VERSION_3)
+ initConstant(env, c, "_LINUX_CAPABILITY_VERSION_3", _LINUX_CAPABILITY_VERSION_3);
+#endif
initConstant(env, c, "MAP_FIXED", MAP_FIXED);
initConstant(env, c, "MAP_POPULATE", MAP_POPULATE);
initConstant(env, c, "MAP_PRIVATE", MAP_PRIVATE);
@@ -406,6 +409,12 @@
initConstant(env, c, "POLLRDNORM", POLLRDNORM);
initConstant(env, c, "POLLWRBAND", POLLWRBAND);
initConstant(env, c, "POLLWRNORM", POLLWRNORM);
+#if defined(PR_CAP_AMBIENT)
+ initConstant(env, c, "PR_CAP_AMBIENT", PR_CAP_AMBIENT);
+#endif
+#if defined(PR_CAP_AMBIENT_RAISE)
+ initConstant(env, c, "PR_CAP_AMBIENT_RAISE", PR_CAP_AMBIENT_RAISE);
+#endif
#if defined(PR_GET_DUMPABLE)
initConstant(env, c, "PR_GET_DUMPABLE", PR_GET_DUMPABLE);
#endif
diff --git a/luni/src/main/native/libcore_io_Linux.cpp b/luni/src/main/native/libcore_io_Linux.cpp
index e9f35c2..1e2f3a5 100644
--- a/luni/src/main/native/libcore_io_Linux.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -29,6 +29,7 @@
#include <pwd.h>
#include <signal.h>
#include <stdlib.h>
+#include <sys/capability.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/prctl.h>
@@ -732,6 +733,154 @@
struct passwd* mResult;
};
+static void AssertException(JNIEnv* env) {
+ if (env->ExceptionCheck() == JNI_FALSE) {
+ env->FatalError("Expected exception");
+ }
+}
+
+// Note for capabilities functions:
+// We assume the calls are rare enough that it does not make sense to cache class objects. The
+// advantage is lower maintenance burden.
+
+static bool ReadStructCapUserHeader(
+ JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
+ if (java_header == nullptr) {
+ jniThrowNullPointerException(env, "header is null");
+ return false;
+ }
+
+ ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
+ if (header_class.get() == nullptr) {
+ return false;
+ }
+
+ {
+ static jfieldID version_fid = env->GetFieldID(header_class.get(), "version", "I");
+ if (version_fid == nullptr) {
+ return false;
+ }
+ c_header->version = env->GetIntField(java_header, version_fid);
+ }
+
+ {
+ static jfieldID pid_fid = env->GetFieldID(header_class.get(), "pid", "I");
+ if (pid_fid == nullptr) {
+ return false;
+ }
+ c_header->pid = env->GetIntField(java_header, pid_fid);
+ }
+
+ return true;
+}
+
+static void SetStructCapUserHeaderVersion(
+ JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
+ ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
+ if (header_class.get() == nullptr) {
+ env->ExceptionClear();
+ return;
+ }
+
+ static jfieldID version_fid = env->GetFieldID(header_class.get(), "version", "I");
+ if (version_fid == nullptr) {
+ env->ExceptionClear();
+ return;
+ }
+ env->SetIntField(java_header, version_fid, c_header->version);
+}
+
+static jobject CreateStructCapUserData(
+ JNIEnv* env, jclass data_class, __user_cap_data_struct* c_data) {
+ if (c_data == nullptr) {
+ // Should not happen.
+ jniThrowNullPointerException(env, "data is null");
+ return nullptr;
+ }
+
+ static jmethodID data_cons = env->GetMethodID(data_class, "<init>", "(III)V");
+ if (data_cons == nullptr) {
+ return nullptr;
+ }
+
+ jint e = static_cast<jint>(c_data->effective);
+ jint p = static_cast<jint>(c_data->permitted);
+ jint i = static_cast<jint>(c_data->inheritable);
+ return env->NewObject(data_class, data_cons, e, p, i);
+}
+
+static bool ReadStructCapUserData(JNIEnv* env, jobject java_data, __user_cap_data_struct* c_data) {
+ if (java_data == nullptr) {
+ jniThrowNullPointerException(env, "data is null");
+ return false;
+ }
+
+ ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
+ if (data_class.get() == nullptr) {
+ return false;
+ }
+
+ {
+ static jfieldID effective_fid = env->GetFieldID(data_class.get(), "effective", "I");
+ if (effective_fid == nullptr) {
+ return false;
+ }
+ c_data->effective = env->GetIntField(java_data, effective_fid);
+ }
+
+ {
+ static jfieldID permitted_fid = env->GetFieldID(data_class.get(), "permitted", "I");
+ if (permitted_fid == nullptr) {
+ return false;
+ }
+ c_data->permitted = env->GetIntField(java_data, permitted_fid);
+ }
+
+
+ {
+ static jfieldID inheritable_fid = env->GetFieldID(data_class.get(), "inheritable", "I");
+ if (inheritable_fid == nullptr) {
+ return false;
+ }
+ c_data->inheritable = env->GetIntField(java_data, inheritable_fid);
+ }
+
+ return true;
+}
+
+static constexpr size_t kMaxCapUserDataLength = 2U;
+#ifdef _LINUX_CAPABILITY_VERSION_1
+static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_1, "Length too small.");
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_2
+static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_2, "Length too small.");
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_3
+static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_3, "Length too small.");
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_4
+static_assert(false, "Unsupported capability version, please update.");
+#endif
+
+static size_t GetCapUserDataLength(uint32_t version) {
+#ifdef _LINUX_CAPABILITY_VERSION_1
+ if (version == _LINUX_CAPABILITY_VERSION_1) {
+ return _LINUX_CAPABILITY_U32S_1;
+ }
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_2
+ if (version == _LINUX_CAPABILITY_VERSION_2) {
+ return _LINUX_CAPABILITY_U32S_2;
+ }
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_3
+ if (version == _LINUX_CAPABILITY_VERSION_3) {
+ return _LINUX_CAPABILITY_U32S_3;
+ }
+#endif
+ return 0;
+}
+
static jobject Linux_accept(JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
sockaddr_storage ss;
socklen_t sl = sizeof(ss);
@@ -776,6 +925,83 @@
(void) NET_FAILURE_RETRY(env, int, bind, javaFd, sa, sa_len);
}
+static jobjectArray Linux_capget(JNIEnv* env, jobject, jobject header) {
+ // Convert Java header struct to kernel datastructure.
+ __user_cap_header_struct cap_header;
+ if (!ReadStructCapUserHeader(env, header, &cap_header)) {
+ AssertException(env);
+ return nullptr;
+ }
+
+ // Call capget.
+ __user_cap_data_struct cap_data[kMaxCapUserDataLength];
+ if (capget(&cap_header, &cap_data[0]) == -1) {
+ // Check for EINVAL. In that case, mutate the header.
+ if (errno == EINVAL) {
+ int saved_errno = errno;
+ SetStructCapUserHeaderVersion(env, header, &cap_header);
+ errno = saved_errno;
+ }
+ throwErrnoException(env, "capget");
+ return nullptr;
+ }
+
+ // Create the result array.
+ ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
+ if (data_class.get() == nullptr) {
+ return nullptr;
+ }
+ size_t result_size = GetCapUserDataLength(cap_header.version);
+ ScopedLocalRef<jobjectArray> result(
+ env, env->NewObjectArray(result_size, data_class.get(), nullptr));
+ if (result.get() == nullptr) {
+ return nullptr;
+ }
+ // Translate the values we got.
+ for (size_t i = 0; i < result_size; ++i) {
+ ScopedLocalRef<jobject> value(
+ env, CreateStructCapUserData(env, data_class.get(), &cap_data[i]));
+ if (value.get() == nullptr) {
+ AssertException(env);
+ return nullptr;
+ }
+ env->SetObjectArrayElement(result.get(), i, value.get());
+ }
+ return result.release();
+}
+
+static void Linux_capset(
+ JNIEnv* env, jobject, jobject header, jobjectArray data) {
+ // Convert Java header struct to kernel datastructure.
+ __user_cap_header_struct cap_header;
+ if (!ReadStructCapUserHeader(env, header, &cap_header)) {
+ AssertException(env);
+ return;
+ }
+ size_t result_size = GetCapUserDataLength(cap_header.version);
+ // Ensure that the array has the expected length.
+ if (env->GetArrayLength(data) != static_cast<jint>(result_size)) {
+ jniThrowExceptionFmt(env,
+ "java/lang/IllegalArgumentException",
+ "Unsupported input length %d (expected %zu)",
+ env->GetArrayLength(data),
+ result_size);
+ return;
+ }
+
+ __user_cap_data_struct cap_data[kMaxCapUserDataLength];
+ // Translate the values we got.
+ for (size_t i = 0; i < result_size; ++i) {
+ ScopedLocalRef<jobject> value(env, env->GetObjectArrayElement(data, i));
+ if (!ReadStructCapUserData(env, value.get(), &cap_data[i])) {
+ AssertException(env);
+ return;
+ }
+ }
+
+ throwIfMinusOne(env, "capset", capset(&cap_header, &cap_data[0]));
+}
+
static void Linux_chmod(JNIEnv* env, jobject, jstring javaPath, jint mode) {
ScopedUtfChars path(env, javaPath);
if (path.c_str() == NULL) {
@@ -2152,6 +2378,10 @@
NATIVE_METHOD(Linux, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
NATIVE_METHOD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
NATIVE_METHOD_OVERLOAD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
+ NATIVE_METHOD(Linux, capget,
+ "(Landroid/system/StructCapUserHeader;)[Landroid/system/StructCapUserData;"),
+ NATIVE_METHOD(Linux, capset,
+ "(Landroid/system/StructCapUserHeader;[Landroid/system/StructCapUserData;)V"),
NATIVE_METHOD(Linux, chmod, "(Ljava/lang/String;I)V"),
NATIVE_METHOD(Linux, chown, "(Ljava/lang/String;II)V"),
NATIVE_METHOD(Linux, close, "(Ljava/io/FileDescriptor;)V"),
diff --git a/luni/src/test/java/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/io/BlockGuardOsTest.java
index 33eb411..567cf2d 100644
--- a/luni/src/test/java/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/io/BlockGuardOsTest.java
@@ -49,6 +49,8 @@
"android_getaddrinfo(java.lang.String,android.system.StructAddrinfo,int)",
"bind(java.io.FileDescriptor,java.net.InetAddress,int)",
"bind(java.io.FileDescriptor,java.net.SocketAddress)",
+ "capget(android.system.StructCapUserHeader)",
+ "capset(android.system.StructCapUserHeader,android.system.StructCapUserData[])",
"dup(java.io.FileDescriptor)",
"dup2(java.io.FileDescriptor,int)",
"environ()",
diff --git a/luni/src/test/java/libcore/java/nio/file/spi/FileTypeDetectorTest.java b/luni/src/test/java/libcore/java/nio/file/spi/FileTypeDetectorTest.java
new file mode 100644
index 0000000..bf6c6b7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/nio/file/spi/FileTypeDetectorTest.java
@@ -0,0 +1,22 @@
+package libcore.java.nio.file.spi;
+
+import org.junit.Test;
+
+import java.nio.file.Paths;
+import java.nio.file.spi.FileTypeDetector;
+
+import static org.junit.Assert.assertEquals;
+
+public class FileTypeDetectorTest {
+
+ @Test
+ public void test_probeFileType() throws Exception {
+ FileTypeDetector defaultFileTypeDetector = sun.nio.fs.DefaultFileTypeDetector.create();
+ // The method uses file extensions to deduce mime type, therefore, it doesn't check for
+ // file existence.
+ assertEquals("text/plain",
+ defaultFileTypeDetector.probeContentType(Paths.get("file.txt")));
+ assertEquals("text/x-java",
+ defaultFileTypeDetector.probeContentType(Paths.get("file.java")));
+ }
+}
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java
index 4a5658c..cbaadd4 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java
@@ -67,13 +67,21 @@
X509CertSelector certSelector = new X509CertSelector();
certSelector.addPathToName(GeneralName.iPAddress, "127.0.0.1");
+ // This constraint matches 127.0.0.1/255.255.255.255 aka 127.0.0.1
byte[] directMatch = { 127, 0, 0, 1, -1, -1, -1, -1 };
assertTrue(certSelector.match(newCertWithNameConstraint(directMatch, excluded)));
- byte[] noMatch = { 127, 0, 0, 2, -1, -1, -1, 127 };
+ // This constraint matches 127.0.0.2/255.255.255.255 aka 127.0.0.2
+ byte[] noMatch = { 127, 0, 0, 2, -1, -1, -1, -1 };
assertFalse(certSelector.match(newCertWithNameConstraint(noMatch, excluded)));
- // TODO: test that requires mask to match
+ // This constraint matches 127.0.0.0/255.255.255.255 aka 127.0.0.0
+ byte[] subnetWithNoMask = { 127, 0, 0, 0, -1, -1, -1, -1 };
+ assertFalse(certSelector.match(newCertWithNameConstraint(subnetWithNoMask, excluded)));
+
+ // This constraint matches 127.0.0.0/255.255.255.0 aka 127.0.0.0/24
+ byte[] maskedMatch = { 127, 0, 0, 0, -1, -1, -1, 0 };
+ assertTrue(certSelector.match(newCertWithNameConstraint(maskedMatch, excluded)));
}
public void testMatchMaskedIpv6NameConstraint() throws Exception {
@@ -84,19 +92,33 @@
X509CertSelector certSelector = new X509CertSelector();
certSelector.addPathToName(GeneralName.iPAddress, "1::1");
+ // This constraint matches 1::1/128 aka 1::1
byte[] directMatch = {
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
assertTrue(certSelector.match(newCertWithNameConstraint(directMatch, excluded)));
+ // This constraint matches 1::2/128 aka 1::2
byte[] noMatch = {
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
assertFalse(certSelector.match(newCertWithNameConstraint(noMatch, excluded)));
- // TODO: test that requires mask to match
+ // This constraint matches 1::/128 aka 1::
+ byte[] subnetWithNoMask = {
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ };
+ assertFalse(certSelector.match(newCertWithNameConstraint(subnetWithNoMask, excluded)));
+
+ // This constraint matches 1::/120
+ byte[] maskedMatch = {
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ };
+ assertTrue(certSelector.match(newCertWithNameConstraint(maskedMatch, excluded)));
}
public void testMatchMalformedSubjectAlternativeName() throws Exception {
diff --git a/non_openjdk_java_files.mk b/non_openjdk_java_files.mk
index e851faf..fd1353f 100644
--- a/non_openjdk_java_files.mk
+++ b/non_openjdk_java_files.mk
@@ -6,6 +6,8 @@
luni/src/main/java/android/system/OsConstants.java \
luni/src/main/java/android/system/PacketSocketAddress.java \
luni/src/main/java/android/system/StructAddrinfo.java \
+ luni/src/main/java/android/system/StructCapUserData.java \
+ luni/src/main/java/android/system/StructCapUserHeader.java \
luni/src/main/java/android/system/StructFlock.java \
luni/src/main/java/android/system/StructGroupReq.java \
luni/src/main/java/android/system/StructGroupSourceReq.java \
@@ -235,31 +237,6 @@
xml/src/main/java/org/xmlpull/v1/sax2/Driver.java \
non_openjdk_java_files := \
- dex/src/main/java/com/android/dex/Annotation.java \
- dex/src/main/java/com/android/dex/ClassData.java \
- dex/src/main/java/com/android/dex/ClassDef.java \
- dex/src/main/java/com/android/dex/Code.java \
- dex/src/main/java/com/android/dex/Dex.java \
- dex/src/main/java/com/android/dex/DexException.java \
- dex/src/main/java/com/android/dex/DexFormat.java \
- dex/src/main/java/com/android/dex/DexIndexOverflowException.java \
- dex/src/main/java/com/android/dex/EncodedValue.java \
- dex/src/main/java/com/android/dex/EncodedValueCodec.java \
- dex/src/main/java/com/android/dex/EncodedValueReader.java \
- dex/src/main/java/com/android/dex/FieldId.java \
- dex/src/main/java/com/android/dex/Leb128.java \
- dex/src/main/java/com/android/dex/MethodId.java \
- dex/src/main/java/com/android/dex/Mutf8.java \
- dex/src/main/java/com/android/dex/ProtoId.java \
- dex/src/main/java/com/android/dex/SizeOf.java \
- dex/src/main/java/com/android/dex/TableOfContents.java \
- dex/src/main/java/com/android/dex/TypeList.java \
- dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java \
- dex/src/main/java/com/android/dex/util/ByteInput.java \
- dex/src/main/java/com/android/dex/util/ByteOutput.java \
- dex/src/main/java/com/android/dex/util/ExceptionWithContext.java \
- dex/src/main/java/com/android/dex/util/FileUtils.java \
- dex/src/main/java/com/android/dex/util/Unsigned.java \
dalvik/src/main/java/dalvik/system/profiler/AsciiHprofWriter.java \
dalvik/src/main/java/dalvik/system/profiler/BinaryHprof.java \
dalvik/src/main/java/dalvik/system/profiler/BinaryHprofReader.java \
diff --git a/ojluni/src/main/java/java/awt/font/NumericShaper.java b/ojluni/src/main/java/java/awt/font/NumericShaper.java
index c8100bf..7e1980e 100644
--- a/ojluni/src/main/java/java/awt/font/NumericShaper.java
+++ b/ojluni/src/main/java/java/awt/font/NumericShaper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -633,7 +633,6 @@
0x06d6, 0x06e5,
0x06e7, 0x06ee,
0x06f0, 0x06fa,
- 0x070f, 0x0710,
0x0711, 0x0712,
0x0730, 0x074d,
0x07a6, 0x07b1,
@@ -644,7 +643,7 @@
0x0825, 0x0828,
0x0829, 0x0830,
0x0859, 0x085e,
- 0x0900, 0x0903,
+ 0x08e4, 0x0903,
0x093a, 0x093b,
0x093c, 0x093d,
0x0941, 0x0949,
@@ -723,6 +722,7 @@
0x1732, 0x1735,
0x1752, 0x1760,
0x1772, 0x1780,
+ 0x17b4, 0x17b6,
0x17b7, 0x17be,
0x17c6, 0x17c7,
0x17c9, 0x17d4,
@@ -750,6 +750,7 @@
0x1b80, 0x1b82,
0x1ba2, 0x1ba6,
0x1ba8, 0x1baa,
+ 0x1bab, 0x1bac,
0x1be6, 0x1be7,
0x1be8, 0x1bea,
0x1bed, 0x1bee,
@@ -760,6 +761,7 @@
0x1cd4, 0x1ce1,
0x1ce2, 0x1ce9,
0x1ced, 0x1cee,
+ 0x1cf4, 0x1cf5,
0x1dc0, 0x1e00,
0x1fbd, 0x1fbe,
0x1fbf, 0x1fc2,
@@ -791,7 +793,8 @@
0x26ad, 0x2800,
0x2900, 0x2c00,
0x2ce5, 0x2ceb,
- 0x2cef, 0x2d00,
+ 0x2cef, 0x2cf2,
+ 0x2cf9, 0x2d00,
0x2d7f, 0x2d80,
0x2de0, 0x3005,
0x3008, 0x3021,
@@ -814,6 +817,7 @@
0xa490, 0xa4d0,
0xa60d, 0xa610,
0xa66f, 0xa680,
+ 0xa69f, 0xa6a0,
0xa6f0, 0xa6f2,
0xa700, 0xa722,
0xa788, 0xa789,
@@ -842,6 +846,8 @@
0xaab7, 0xaab9,
0xaabe, 0xaac0,
0xaac1, 0xaac2,
+ 0xaaec, 0xaaee,
+ 0xaaf6, 0xab01,
0xabe5, 0xabe6,
0xabe8, 0xabe9,
0xabed, 0xabf0,
@@ -867,6 +873,16 @@
0x11080, 0x11082,
0x110b3, 0x110b7,
0x110b9, 0x110bb,
+ 0x11100, 0x11103,
+ 0x11127, 0x1112c,
+ 0x1112d, 0x11136,
+ 0x11180, 0x11182,
+ 0x111b6, 0x111bf,
+ 0x116ab, 0x116ac,
+ 0x116ad, 0x116ae,
+ 0x116b0, 0x116b6,
+ 0x116b7, 0x116c0,
+ 0x16f8f, 0x16f93,
0x1d167, 0x1d16a,
0x1d173, 0x1d183,
0x1d185, 0x1d18c,
@@ -877,7 +893,9 @@
0x1d74f, 0x1d750,
0x1d789, 0x1d78a,
0x1d7c3, 0x1d7c4,
- 0x1d7ce, 0x1f110,
+ 0x1d7ce, 0x1ee00,
+ 0x1eef0, 0x1f110,
+ 0x1f16a, 0x1f170,
0x1f300, 0x1f48c,
0x1f48d, 0x1f524,
0x1f525, 0x20000,
@@ -1194,7 +1212,7 @@
* For example, to check if a shaper shapes to Arabic, you would use the
* following:
* <blockquote>
- * <code>if ((shaper.getRanges() & shaper.ARABIC) != 0) { ... </code>
+ * {@code if ((shaper.getRanges() & shaper.ARABIC) != 0) { ... }
* </blockquote>
*
* <p>Note that this method supports only the bit mask-based
diff --git a/ojluni/src/main/java/java/beans/PropertyChangeEvent.java b/ojluni/src/main/java/java/beans/PropertyChangeEvent.java
index 55397ef..eeaa651 100644
--- a/ojluni/src/main/java/java/beans/PropertyChangeEvent.java
+++ b/ojluni/src/main/java/java/beans/PropertyChangeEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package java.beans;
+import java.util.EventObject;
+
/**
* A "PropertyChange" event gets delivered whenever a bean changes a "bound"
* or "constrained" property. A PropertyChangeEvent object is sent as an
@@ -42,21 +44,21 @@
* arbitrary set of if its properties have changed. In this case the
* old and new values should also be null.
*/
-
-public class PropertyChangeEvent extends java.util.EventObject {
+public class PropertyChangeEvent extends EventObject {
private static final long serialVersionUID = 7042693688939648123L;
/**
- * Constructs a new <code>PropertyChangeEvent</code>.
+ * Constructs a new {@code PropertyChangeEvent}.
*
- * @param source The bean that fired the event.
- * @param propertyName The programmatic name of the property
- * that was changed.
- * @param oldValue The old value of the property.
- * @param newValue The new value of the property.
+ * @param source the bean that fired the event
+ * @param propertyName the programmatic name of the property that was changed
+ * @param oldValue the old value of the property
+ * @param newValue the new value of the property
+ *
+ * @throws IllegalArgumentException if {@code source} is {@code null}
*/
public PropertyChangeEvent(Object source, String propertyName,
- Object oldValue, Object newValue) {
+ Object oldValue, Object newValue) {
super(source);
this.propertyName = propertyName;
this.newValue = newValue;
diff --git a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
index 270912c..d55ae76 100644
--- a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
+++ b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -156,7 +156,7 @@
* <code>PropertyChangeListenerProxy</code>, perform the cast, and examine
* the parameter.
*
- * <pre>
+ * <pre>{@code
* PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
* for (int i = 0; i < listeners.length; i++) {
* if (listeners[i] instanceof PropertyChangeListenerProxy) {
@@ -168,7 +168,7 @@
* }
* }
* }
- *</pre>
+ * }</pre>
*
* @see PropertyChangeListenerProxy
* @return all of the <code>PropertyChangeListeners</code> added or an
@@ -431,7 +431,7 @@
listeners = entry.getValue();
} else {
if (children == null) {
- children = new Hashtable<String, PropertyChangeSupport>();
+ children = new Hashtable<>();
}
PropertyChangeSupport pcs = new PropertyChangeSupport(this.source);
pcs.map.set(null, entry.getValue());
@@ -460,6 +460,7 @@
ObjectInputStream.GetField fields = s.readFields();
+ @SuppressWarnings("unchecked")
Hashtable<String, PropertyChangeSupport> children = (Hashtable<String, PropertyChangeSupport>) fields.get("children", null);
this.source = fields.get("source", null);
fields.get("propertyChangeSupportSerializedDataVersion", 2);
diff --git a/ojluni/src/main/java/java/lang/Class.java b/ojluni/src/main/java/java/lang/Class.java
index b298186..3717cd7 100644
--- a/ojluni/src/main/java/java/lang/Class.java
+++ b/ojluni/src/main/java/java/lang/Class.java
@@ -27,7 +27,6 @@
package java.lang;
import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
import java.io.InputStream;
import java.io.Serializable;
diff --git a/ojluni/src/main/java/java/lang/reflect/Field.java b/ojluni/src/main/java/java/lang/reflect/Field.java
index 8658303..a691766 100644
--- a/ojluni/src/main/java/java/lang/reflect/Field.java
+++ b/ojluni/src/main/java/java/lang/reflect/Field.java
@@ -27,7 +27,6 @@
package java.lang.reflect;
import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
import java.lang.annotation.Annotation;
import java.util.Objects;
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java b/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java
index 680795c..d05d22f 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,13 +26,16 @@
package sun.security.provider.certpath;
import java.io.IOException;
-import java.util.Date;
-
+import java.math.BigInteger;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.cert.X509CertSelector;
import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.Date;
+import sun.security.util.Debug;
+import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream;
import sun.security.x509.SerialNumber;
import sun.security.x509.KeyIdentifier;
@@ -40,26 +43,27 @@
/**
* An adaptable X509 certificate selector for forward certification path
- * building.
+ * building. This selector overrides the default X509CertSelector matching
+ * rules for the subjectKeyIdentifier and serialNumber criteria, and adds
+ * additional rules for certificate validity.
*
* @since 1.7
*/
class AdaptableX509CertSelector extends X509CertSelector {
+
+ private static final Debug debug = Debug.getInstance("certpath");
+
// The start date of a validity period.
private Date startDate;
// The end date of a validity period.
private Date endDate;
- // Is subject key identifier sensitive?
- private boolean isSKIDSensitive = false;
+ // The subject key identifier
+ private byte[] ski;
- // Is serial number sensitive?
- private boolean isSNSensitive = false;
-
- AdaptableX509CertSelector() {
- super();
- }
+ // The serial number
+ private BigInteger serial;
/**
* Sets the criterion of the X509Certificate validity period.
@@ -86,51 +90,70 @@
}
/**
- * Parse the authority key identifier extension.
- *
- * If the keyIdentifier field of the extension is non-null, set the
- * subjectKeyIdentifier criterion. If the authorityCertSerialNumber
- * field is non-null, set the serialNumber criterion.
- *
- * Note that we will not set the subject criterion according to the
- * authorityCertIssuer field of the extension. The caller MUST set
- * the subject criterion before call match().
- *
- * @param akidext the authorityKeyIdentifier extension
+ * This selector overrides the subjectKeyIdentifier matching rules of
+ * X509CertSelector, so it throws IllegalArgumentException if this method
+ * is ever called.
*/
- void parseAuthorityKeyIdentifierExtension(
- AuthorityKeyIdentifierExtension akidext) throws IOException {
- if (akidext != null) {
- KeyIdentifier akid = (KeyIdentifier)akidext.get(
- AuthorityKeyIdentifierExtension.KEY_ID);
+ @Override
+ public void setSubjectKeyIdentifier(byte[] subjectKeyID) {
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * This selector overrides the serialNumber matching rules of
+ * X509CertSelector, so it throws IllegalArgumentException if this method
+ * is ever called.
+ */
+ @Override
+ public void setSerialNumber(BigInteger serial) {
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Sets the subjectKeyIdentifier and serialNumber criteria from the
+ * authority key identifier extension.
+ *
+ * The subjectKeyIdentifier criterion is set to the keyIdentifier field
+ * of the extension, or null if it is empty. The serialNumber criterion
+ * is set to the authorityCertSerialNumber field, or null if it is empty.
+ *
+ * Note that we do not set the subject criterion to the
+ * authorityCertIssuer field of the extension. The caller MUST set
+ * the subject criterion before calling match().
+ *
+ * @param ext the authorityKeyIdentifier extension
+ * @throws IOException if there is an error parsing the extension
+ */
+ void setSkiAndSerialNumber(AuthorityKeyIdentifierExtension ext)
+ throws IOException {
+
+ ski = null;
+ serial = null;
+
+ if (ext != null) {
+ KeyIdentifier akid = (KeyIdentifier)ext.get(
+ AuthorityKeyIdentifierExtension.KEY_ID);
if (akid != null) {
- // Do not override the previous setting for initial selection.
- if (isSKIDSensitive || getSubjectKeyIdentifier() == null) {
- DerOutputStream derout = new DerOutputStream();
- derout.putOctetString(akid.getIdentifier());
- super.setSubjectKeyIdentifier(derout.toByteArray());
-
- isSKIDSensitive = true;
- }
+ DerOutputStream derout = new DerOutputStream();
+ derout.putOctetString(akid.getIdentifier());
+ ski = derout.toByteArray();
}
-
- SerialNumber asn = (SerialNumber)akidext.get(
- AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
+ SerialNumber asn = (SerialNumber)ext.get(
+ AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
if (asn != null) {
- // Do not override the previous setting for initial selection.
- if (isSNSensitive || getSerialNumber() == null) {
- super.setSerialNumber(asn.getNumber());
- isSNSensitive = true;
- }
+ serial = asn.getNumber();
}
-
- // the subject criterion should be set by the caller.
+ // the subject criterion should be set by the caller
}
}
/**
* Decides whether a <code>Certificate</code> should be selected.
*
+ * This method overrides the matching rules for the subjectKeyIdentifier
+ * and serialNumber criteria and adds additional rules for certificate
+ * validity.
+ *
* For the purpose of compatibility, when a certificate is of
* version 1 and version 2, or the certificate does not include
* a subject key identifier extension, the selection criterion
@@ -138,12 +161,28 @@
*/
@Override
public boolean match(Certificate cert) {
- if (!(cert instanceof X509Certificate)) {
+ X509Certificate xcert = (X509Certificate)cert;
+
+ // match subject key identifier
+ if (!matchSubjectKeyID(xcert)) {
return false;
}
- X509Certificate xcert = (X509Certificate)cert;
+ // In practice, a CA may replace its root certificate and require that
+ // the existing certificate is still valid, even if the AKID extension
+ // does not match the replacement root certificate fields.
+ //
+ // Conservatively, we only support the replacement for version 1 and
+ // version 2 certificate. As for version 3, the certificate extension
+ // may contain sensitive information (for example, policies), the
+ // AKID need to be respected to seek the exact certificate in case
+ // of key or certificate abuse.
int version = xcert.getVersion();
+ if (serial != null && version > 2) {
+ if (!serial.equals(xcert.getSerialNumber())) {
+ return false;
+ }
+ }
// Check the validity period for version 1 and 2 certificate.
if (version < 3) {
@@ -154,7 +193,6 @@
return false;
}
}
-
if (endDate != null) {
try {
xcert.checkValidity(endDate);
@@ -164,26 +202,50 @@
}
}
- // If no SubjectKeyIdentifier extension, don't bother to check it.
- if (isSKIDSensitive &&
- (version < 3 || xcert.getExtensionValue("2.5.29.14") == null)) {
- setSubjectKeyIdentifier(null);
+
+ if (!super.match(cert)) {
+ return false;
}
- // In practice, a CA may replace its root certificate and require that
- // the existing certificate is still valid, even if the AKID extension
- // does not match the replacement root certificate fields.
- //
- // Conservatively, we only support the replacement for version 1 and
- // version 2 certificate. As for version 2, the certificate extension
- // may contain sensitive information (for example, policies), the
- // AKID need to be respected to seek the exact certificate in case
- // of key or certificate abuse.
- if (isSNSensitive && version < 3) {
- setSerialNumber(null);
- }
+ return true;
+ }
- return super.match(cert);
+ /*
+ * Match on subject key identifier extension value. These matching rules
+ * are identical to X509CertSelector except that if the certificate does
+ * not have a subject key identifier extension, it returns true.
+ */
+ private boolean matchSubjectKeyID(X509Certificate xcert) {
+ if (ski == null) {
+ return true;
+ }
+ try {
+ byte[] extVal = xcert.getExtensionValue("2.5.29.14");
+ if (extVal == null) {
+ if (debug != null) {
+ debug.println("AdaptableX509CertSelector.match: "
+ + "no subject key ID extension");
+ }
+ return true;
+ }
+ DerInputStream in = new DerInputStream(extVal);
+ byte[] certSubjectKeyID = in.getOctetString();
+ if (certSubjectKeyID == null ||
+ !Arrays.equals(ski, certSubjectKeyID)) {
+ if (debug != null) {
+ debug.println("AdaptableX509CertSelector.match: "
+ + "subject key IDs don't match");
+ }
+ return false;
+ }
+ } catch (IOException ex) {
+ if (debug != null) {
+ debug.println("AdaptableX509CertSelector.match: "
+ + "exception in subject key ID check");
+ }
+ return false;
+ }
+ return true;
}
@Override
@@ -198,6 +260,9 @@
copy.endDate = (Date)endDate.clone();
}
+ if (ski != null) {
+ copy.ski = ski.clone();
+ }
return copy;
}
}
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java b/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java
index 34bfbba..bec4f4d 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java
@@ -753,9 +753,7 @@
* issued. [section 5.2.1, RFC 2459]
*/
AuthorityKeyIdentifierExtension crlAKID = crl.getAuthKeyIdExtension();
- if (crlAKID != null) {
- issuerSelector.parseAuthorityKeyIdentifierExtension(crlAKID);
- }
+ issuerSelector.setSkiAndSerialNumber(crlAKID);
matched = issuerSelector.match(cert);
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java b/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java
index ae3e628..b5d15b2 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java
@@ -269,7 +269,7 @@
*/
AuthorityKeyIdentifierExtension akidext =
currentState.cert.getAuthorityKeyIdentifierExtension();
- caSelector.parseAuthorityKeyIdentifierExtension(akidext);
+ caSelector.setSkiAndSerialNumber(akidext);
/*
* check the validity period
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java b/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java
index f8dfff1..492e851 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,7 +103,7 @@
*/
try {
X509CertImpl firstCertImpl = X509CertImpl.toImpl(firstCert);
- selector.parseAuthorityKeyIdentifierExtension(
+ selector.setSkiAndSerialNumber(
firstCertImpl.getAuthorityKeyIdentifierExtension());
} catch (CertificateException | IOException e) {
// ignore
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java b/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java
index 19b41f6..f38e7dc 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1035,6 +1035,9 @@
boolean signFlag = true;
List<? extends Certificate> cpList =
cpbr.getCertPath().getCertificates();
+ if (cpList.isEmpty()) {
+ return;
+ }
try {
for (int i = cpList.size()-1; i >= 0; i-- ) {
X509Certificate cert = (X509Certificate)cpList.get(i);
diff --git a/ojluni/src/test/java/security/cert/AKISerialNumberTest.java b/ojluni/src/test/java/security/cert/AKISerialNumberTest.java
new file mode 100644
index 0000000..aae931d
--- /dev/null
+++ b/ojluni/src/test/java/security/cert/AKISerialNumberTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8025708
+ * @summary make sure a PKIX CertPathBuilder can build a path when an
+ * intermediate CA certificate contains an AKI extension with a key
+ * identifier and no serial number and the end-entity certificate contains
+ * an AKI extension with both a key identifier and a serial number.
+ */
+// Android-changed: Adapted from
+// jdk/test/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java
+// Android-changed: Added package & Test import
+package test.java.security.cert;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.*;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Collections;
+
+public class AKISerialNumberTest {
+
+ private static final String ROOT_CERT =
+ "MIICfTCCAeagAwIBAgIBATANBgkqhkiG9w0BAQUFADB3MQ0wCwYDVQQDEwRSb290\n" +
+ "MRYwFAYDVQQLEw1UZXN0IE9yZyBVbml0MREwDwYDVQQKEwhUZXN0IE9yZzEWMBQG\n" +
+ "A1UEBxMNVGVzdCBMb2NhbGl0eTEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czELMAkG\n" +
+ "A1UEBhMCVVMwHhcNMTQwMjAxMDUwMDAwWhcNMjQwMjAxMDUwMDAwWjB3MQ0wCwYD\n" +
+ "VQQDEwRSb290MRYwFAYDVQQLEw1UZXN0IE9yZyBVbml0MREwDwYDVQQKEwhUZXN0\n" +
+ "IE9yZzEWMBQGA1UEBxMNVGVzdCBMb2NhbGl0eTEWMBQGA1UECBMNTWFzc2FjaHVz\n" +
+ "ZXR0czELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJvL\n" +
+ "cZu6Rzf9IrduEDjJxEFv5uBvUNMlIAph7NhfmFH9puPW3Ksci4a5yTCzxI9VeVf3\n" +
+ "oYZ/UrZdF+mNZmS23RUh71X5tjMO+xew196M1xNpCRLbjcZ6i4tNdZYkdRIe8ejN\n" +
+ "sbBoD7OAvPbQqTygeG4jYjK6ODofSrba3BndNoFxAgMBAAGjGTAXMBUGA1UdEwEB\n" +
+ "/wQLMAkBAf8CBH////8wDQYJKoZIhvcNAQEFBQADgYEATvCqn69pNHv0zLiZAXk7\n" +
+ "3AKwAoza0wa+1S2rVuZGfBWbV7CxmBHbgcDDbU7/I8pQVkCwOHNkVFnBgNpMuAvU\n" +
+ "aDyrHSNS/av5d1yk5WAuGX2B9mSwZdhnAvtz2fsV1q9NptdF54EkIiKtQQmTGnr9\n" +
+ "TID8CFEk/qje+AB272B1UJw=\n";
+
+ /**
+ * This certificate contains an AuthorityKeyIdentifier with only the
+ * keyIdentifier field filled in.
+ */
+ private static final String INT_CERT_WITH_KEYID_AKI =
+ "MIICqTCCAhKgAwIBAgIBAjANBgkqhkiG9w0BAQUFADB3MQ0wCwYDVQQDEwRSb290\n" +
+ "MRYwFAYDVQQLEw1UZXN0IE9yZyBVbml0MREwDwYDVQQKEwhUZXN0IE9yZzEWMBQG\n" +
+ "A1UEBxMNVGVzdCBMb2NhbGl0eTEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czELMAkG\n" +
+ "A1UEBhMCVVMwHhcNMTQwMjAxMDUwMDAwWhcNMjQwMjAxMDUwMDAwWjCBhDEaMBgG\n" +
+ "A1UEAxMRSW50ZXJtZWRpYXRlIENBIDIxFjAUBgNVBAsTDVRlc3QgT3JnIFVuaXQx\n" +
+ "ETAPBgNVBAoTCFRlc3QgT3JnMRYwFAYDVQQHEw1UZXN0IExvY2FsaXR5MRYwFAYD\n" +
+ "VQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEF\n" +
+ "AAOBjQAwgYkCgYEAwKTZekCqb9F9T54s2IXjkQbmLIjQamMpkUlZNrpjjNq9CpTT\n" +
+ "POkfxv2UPwzTz3Ij4XFL/kJFBLm8NUOsS5xPJ62pGoZBPw9R0iMTsTce+Fpukqnr\n" +
+ "I+8jTRaAvr0tR3pqrE6uHKg7dWYN2SsWesDia/LHhwEN38yyWtSuTTLo4hcCAwEA\n" +
+ "AaM3MDUwHwYDVR0jBBgwFoAU6gZP1pO8v7+i8gsFf1gWTf/j3PkwEgYDVR0TAQH/\n" +
+ "BAgwBgEB/wIBADANBgkqhkiG9w0BAQUFAAOBgQAQxeQruav4AqQM4gmEfrHr5hOq\n" +
+ "mB2CNJ1ZqVfpDZ8GHijncKTpjNoXzzQtV23Ge+39JHOVBNWtk+aghB3iu6xGq7Qn\n" +
+ "HlBhg9meqHFqd3igDDD/jhABL2/bEo/M9rv6saYWDFZ8nCIEE6iTLTpRRko4W2Xb\n" +
+ "DyzMzMsO1kPNrJaxRg==\n";
+
+ /**
+ * This certificate contains an AuthorityKeyIdentifier with all 3 fields
+ * (keyIdentifier, authorityCertIssuer, and authorityCertSerialNumber)
+ * filled in.
+ */
+ private static final String EE_CERT_WITH_FULL_AKI =
+ "MIIDLjCCApegAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBhDEaMBgGA1UEAxMRSW50\n" +
+ "ZXJtZWRpYXRlIENBIDIxFjAUBgNVBAsTDVRlc3QgT3JnIFVuaXQxETAPBgNVBAoT\n" +
+ "CFRlc3QgT3JnMRYwFAYDVQQHEw1UZXN0IExvY2FsaXR5MRYwFAYDVQQIEw1NYXNz\n" +
+ "YWNodXNldHRzMQswCQYDVQQGEwJVUzAeFw0xNDAyMDEwNTAwMDBaFw0yNDAyMDEw\n" +
+ "NTAwMDBaMH0xEzARBgNVBAMTCkVuZCBFbnRpdHkxFjAUBgNVBAsTDVRlc3QgT3Jn\n" +
+ "IFVuaXQxETAPBgNVBAoTCFRlc3QgT3JnMRYwFAYDVQQHEw1UZXN0IExvY2FsaXR5\n" +
+ "MRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG\n" +
+ "9w0BAQEFAAOBjQAwgYkCgYEAqady46PdwlKHVP1iaP11CxVyL6cDlPjpwhHCcIUv\n" +
+ "nKHbzdamqmHebDcWVBNN/I0TLNCl3ga7n8KyygSN379fG7haU8SNjpy4IDAXM0/x\n" +
+ "mwTWNTbKfJEkSoiqx1WUy2JTzRUMhgYPguQNECPxBXAdQrthZ7wQosv6Ro2ySP9O\n" +
+ "YqsCAwEAAaOBtTCBsjCBoQYDVR0jBIGZMIGWgBQdeoKxTvlTgW2KgprD69vgHV4X\n" +
+ "kKF7pHkwdzENMAsGA1UEAxMEUm9vdDEWMBQGA1UECxMNVGVzdCBPcmcgVW5pdDER\n" +
+ "MA8GA1UEChMIVGVzdCBPcmcxFjAUBgNVBAcTDVRlc3QgTG9jYWxpdHkxFjAUBgNV\n" +
+ "BAgTDU1hc3NhY2h1c2V0dHMxCzAJBgNVBAYTAlVTggECMAwGA1UdEwEB/wQCMAAw\n" +
+ "DQYJKoZIhvcNAQEFBQADgYEAuG4mM1nLF7STQWwmceELZEl49ntapH/RVoekknmd\n" +
+ "aNzcL4XQf6BTl8KFUXuThHaukQnGIzFbSZV0hrpSQ5fTN2cSZgD4Fji+HuNURmmd\n" +
+ "+Kayl0piHyO1FSbrty0TFhlVNvzKXjmMp6Jdn42KyGOSCoROQcvUWN6xkV3Hvrei\n" +
+ "0ZE=\n";
+
+ private static Base64.Decoder b64Decoder = Base64.getMimeDecoder();
+ private static CertificateFactory cf;
+
+ // Android-changed: Removed args & added @Test
+ @Test
+ public static void main() throws Exception {
+
+ cf = CertificateFactory.getInstance("X.509");
+
+ X509Certificate rootCert = getCertFromMimeEncoding(ROOT_CERT);
+ TrustAnchor anchor = new TrustAnchor(rootCert, null);
+
+ X509Certificate eeCert = getCertFromMimeEncoding(EE_CERT_WITH_FULL_AKI);
+ X509Certificate intCert = getCertFromMimeEncoding(INT_CERT_WITH_KEYID_AKI);
+
+ X509CertSelector sel = new X509CertSelector();
+ sel.setCertificate(eeCert);
+ PKIXBuilderParameters params = new PKIXBuilderParameters
+ (Collections.singleton(anchor), sel);
+ params.setRevocationEnabled(false);
+
+ ArrayList<X509Certificate> certs = new ArrayList<>();
+ certs.add(intCert);
+ certs.add(eeCert);
+ CollectionCertStoreParameters ccsp =
+ new CollectionCertStoreParameters(certs);
+ CertStore cs = CertStore.getInstance("Collection", ccsp);
+ params.addCertStore(cs);
+
+ CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
+ CertPathBuilderResult res = cpb.build(params);
+ }
+
+ private static X509Certificate getCertFromMimeEncoding(String encoded)
+ throws CertificateException
+ {
+ byte[] bytes = b64Decoder.decode(encoded);
+ ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
+ return (X509Certificate)cf.generateCertificate(stream);
+ }
+}
\ No newline at end of file
diff --git a/tools/docs/crypto/data/crypto_support.json b/tools/docs/crypto/data/crypto_support.json
index 0a32e57..38834d9 100644
--- a/tools/docs/crypto/data/crypto_support.json
+++ b/tools/docs/crypto/data/crypto_support.json
@@ -16,7 +16,7 @@
},
{
"deprecated": "true",
- "name": "DESEDE",
+ "name": "DESede",
"supported_api_levels": "1-8"
},
{
@@ -45,7 +45,7 @@
"supported_api_levels": "1+"
},
{
- "name": "DESEDE",
+ "name": "DESede",
"supported_api_levels": "1+"
},
{
@@ -74,43 +74,43 @@
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHHMACSHA1ANDAES_128",
+ "name": "PBEwithHmacSHA1AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA1ANDAES_256",
+ "name": "PBEwithHmacSHA1AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA224ANDAES_128",
+ "name": "PBEwithHmacSHA224AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA224ANDAES_256",
+ "name": "PBEwithHmacSHA224AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256ANDAES_128",
+ "name": "PBEwithHmacSHA256AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256ANDAES_256",
+ "name": "PBEwithHmacSHA256AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384ANDAES_128",
+ "name": "PBEwithHmacSHA384AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384ANDAES_256",
+ "name": "PBEwithHmacSHA384AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512ANDAES_128",
+ "name": "PBEwithHmacSHA512AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512ANDAES_256",
+ "name": "PBEwithHmacSHA512AndAES_256",
"supported_api_levels": "26+"
},
{
@@ -145,7 +145,7 @@
{
"algorithms": [
{
- "name": "COLLECTION",
+ "name": "Collection",
"supported_api_levels": "1+"
}
],
@@ -163,63 +163,63 @@
{
"algorithms": [
{
- "name": "AES/CBC/ISO10126PADDING",
+ "name": "AES/CBC/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CBC/NOPADDING",
+ "name": "AES/CBC/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CBC/PKCS5PADDING",
+ "name": "AES/CBC/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CFB/ISO10126PADDING",
+ "name": "AES/CFB/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CFB/NOPADDING",
+ "name": "AES/CFB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CFB/PKCS5PADDING",
+ "name": "AES/CFB/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CTR/ISO10126PADDING",
+ "name": "AES/CTR/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CTR/NOPADDING",
+ "name": "AES/CTR/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CTR/PKCS5PADDING",
+ "name": "AES/CTR/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CTS/ISO10126PADDING",
+ "name": "AES/CTS/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CTS/NOPADDING",
+ "name": "AES/CTS/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "AES/CTS/PKCS5PADDING",
+ "name": "AES/CTS/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/ECB/ISO10126PADDING",
+ "name": "AES/ECB/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/ECB/NOPADDING",
+ "name": "AES/ECB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "AES/ECB/PKCS5PADDING",
+ "name": "AES/ECB/PKCS5Padding",
"supported_api_levels": "1+"
},
{
@@ -227,339 +227,339 @@
"supported_api_levels": "10+"
},
{
- "name": "AES/OFB/ISO10126PADDING",
+ "name": "AES/OFB/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES/OFB/NOPADDING",
+ "name": "AES/OFB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "AES/OFB/PKCS5PADDING",
+ "name": "AES/OFB/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "AES_128/CBC/NOPADDING",
+ "name": "AES_128/CBC/NoPadding",
"supported_api_levels": "26+"
},
{
- "name": "AES_128/CBC/PKCS5PADDING",
+ "name": "AES_128/CBC/PKCS5Padding",
"supported_api_levels": "26+"
},
{
- "name": "AES_128/ECB/NOPADDING",
+ "name": "AES_128/ECB/NoPadding",
"supported_api_levels": "26+"
},
{
- "name": "AES_128/ECB/PKCS5PADDING",
+ "name": "AES_128/ECB/PKCS5Padding",
"supported_api_levels": "26+"
},
{
- "name": "AES_128/GCM/NOPADDING",
+ "name": "AES_128/GCM/NoPadding",
"supported_api_levels": "26+"
},
{
- "name": "AES_256/CBC/NOPADDING",
+ "name": "AES_256/CBC/NoPadding",
"supported_api_levels": "26+"
},
{
- "name": "AES_256/CBC/PKCS5PADDING",
+ "name": "AES_256/CBC/PKCS5Padding",
"supported_api_levels": "26+"
},
{
- "name": "AES_256/ECB/NOPADDING",
+ "name": "AES_256/ECB/NoPadding",
"supported_api_levels": "26+"
},
{
- "name": "AES_256/ECB/PKCS5PADDING",
+ "name": "AES_256/ECB/PKCS5Padding",
"supported_api_levels": "26+"
},
{
- "name": "AES_256/GCM/NOPADDING",
+ "name": "AES_256/GCM/NoPadding",
"supported_api_levels": "26+"
},
{
- "name": "ARC4/ECB/NOPADDING",
+ "name": "ARC4/ECB/NoPadding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CBC/ISO10126PADDING",
+ "name": "BLOWFISH/CBC/ISO10126Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CBC/NOPADDING",
+ "name": "BLOWFISH/CBC/NoPadding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CBC/PKCS5PADDING",
+ "name": "BLOWFISH/CBC/PKCS5Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CFB/ISO10126PADDING",
+ "name": "BLOWFISH/CFB/ISO10126Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CFB/NOPADDING",
+ "name": "BLOWFISH/CFB/NoPadding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CFB/PKCS5PADDING",
+ "name": "BLOWFISH/CFB/PKCS5Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CTR/ISO10126PADDING",
+ "name": "BLOWFISH/CTR/ISO10126Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CTR/NOPADDING",
+ "name": "BLOWFISH/CTR/NoPadding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CTR/PKCS5PADDING",
+ "name": "BLOWFISH/CTR/PKCS5Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CTS/ISO10126PADDING",
+ "name": "BLOWFISH/CTS/ISO10126Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CTS/NOPADDING",
+ "name": "BLOWFISH/CTS/NoPadding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/CTS/PKCS5PADDING",
+ "name": "BLOWFISH/CTS/PKCS5Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/ECB/ISO10126PADDING",
+ "name": "BLOWFISH/ECB/ISO10126Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/ECB/NOPADDING",
+ "name": "BLOWFISH/ECB/NoPadding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/ECB/PKCS5PADDING",
+ "name": "BLOWFISH/ECB/PKCS5Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/OFB/ISO10126PADDING",
+ "name": "BLOWFISH/OFB/ISO10126Padding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/OFB/NOPADDING",
+ "name": "BLOWFISH/OFB/NoPadding",
"supported_api_levels": "10+"
},
{
- "name": "BLOWFISH/OFB/PKCS5PADDING",
+ "name": "BLOWFISH/OFB/PKCS5Padding",
"supported_api_levels": "10+"
},
{
- "name": "DES/CBC/ISO10126PADDING",
+ "name": "DES/CBC/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CBC/NOPADDING",
+ "name": "DES/CBC/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CBC/PKCS5PADDING",
+ "name": "DES/CBC/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CFB/ISO10126PADDING",
+ "name": "DES/CFB/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CFB/NOPADDING",
+ "name": "DES/CFB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CFB/PKCS5PADDING",
+ "name": "DES/CFB/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CTR/ISO10126PADDING",
+ "name": "DES/CTR/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CTR/NOPADDING",
+ "name": "DES/CTR/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CTR/PKCS5PADDING",
+ "name": "DES/CTR/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CTS/ISO10126PADDING",
+ "name": "DES/CTS/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CTS/NOPADDING",
+ "name": "DES/CTS/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DES/CTS/PKCS5PADDING",
+ "name": "DES/CTS/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/ECB/ISO10126PADDING",
+ "name": "DES/ECB/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/ECB/NOPADDING",
+ "name": "DES/ECB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DES/ECB/PKCS5PADDING",
+ "name": "DES/ECB/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/OFB/ISO10126PADDING",
+ "name": "DES/OFB/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DES/OFB/NOPADDING",
+ "name": "DES/OFB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DES/OFB/PKCS5PADDING",
+ "name": "DES/OFB/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CBC/ISO10126PADDING",
+ "name": "DESede/CBC/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CBC/NOPADDING",
+ "name": "DESede/CBC/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CBC/PKCS5PADDING",
+ "name": "DESede/CBC/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CFB/ISO10126PADDING",
+ "name": "DESede/CFB/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CFB/NOPADDING",
+ "name": "DESede/CFB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CFB/PKCS5PADDING",
+ "name": "DESede/CFB/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CTR/ISO10126PADDING",
+ "name": "DESede/CTR/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CTR/NOPADDING",
+ "name": "DESede/CTR/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CTR/PKCS5PADDING",
+ "name": "DESede/CTR/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CTS/ISO10126PADDING",
+ "name": "DESede/CTS/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CTS/NOPADDING",
+ "name": "DESede/CTS/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/CTS/PKCS5PADDING",
+ "name": "DESede/CTS/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/ECB/ISO10126PADDING",
+ "name": "DESede/ECB/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/ECB/NOPADDING",
+ "name": "DESede/ECB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/ECB/PKCS5PADDING",
+ "name": "DESede/ECB/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/OFB/ISO10126PADDING",
+ "name": "DESede/OFB/ISO10126Padding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/OFB/NOPADDING",
+ "name": "DESede/OFB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "DESEDE/OFB/PKCS5PADDING",
+ "name": "DESede/OFB/PKCS5Padding",
"supported_api_levels": "1+"
},
{
- "name": "RSA/ECB/NOPADDING",
+ "name": "RSA/ECB/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "RSA/ECB/OAEPPADDING",
+ "name": "RSA/ECB/OAEPPadding",
"supported_api_levels": "1+"
},
{
- "name": "RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING",
+ "name": "RSA/ECB/OAEPwithSHA-1andMGF1Padding",
"supported_api_levels": "10+"
},
{
- "name": "RSA/ECB/OAEPWITHSHA-224ANDMGF1PADDING",
+ "name": "RSA/ECB/OAEPwithSHA-224andMGF1Padding",
"supported_api_levels": "23+"
},
{
- "name": "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING",
+ "name": "RSA/ECB/OAEPwithSHA-256andMGF1Padding",
"supported_api_levels": "10+"
},
{
- "name": "RSA/ECB/OAEPWITHSHA-384ANDMGF1PADDING",
+ "name": "RSA/ECB/OAEPwithSHA-384andMGF1Padding",
"supported_api_levels": "23+"
},
{
- "name": "RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING",
+ "name": "RSA/ECB/OAEPwithSHA-512andMGF1Padding",
"supported_api_levels": "23+"
},
{
- "name": "RSA/ECB/PKCS1PADDING",
+ "name": "RSA/ECB/PKCS1Padding",
"supported_api_levels": "1+"
},
{
- "name": "RSA/NONE/NOPADDING",
+ "name": "RSA/NONE/NoPadding",
"supported_api_levels": "1+"
},
{
- "name": "RSA/NONE/OAEPPADDING",
+ "name": "RSA/NONE/OAEPPadding",
"supported_api_levels": "1+"
},
{
- "name": "RSA/NONE/OAEPWITHSHA-1ANDMGF1PADDING",
+ "name": "RSA/NONE/OAEPwithSHA-1andMGF1Padding",
"supported_api_levels": "10+"
},
{
- "name": "RSA/NONE/OAEPWITHSHA-224ANDMGF1PADDING",
+ "name": "RSA/NONE/OAEPwithSHA-224andMGF1Padding",
"supported_api_levels": "23+"
},
{
- "name": "RSA/NONE/OAEPWITHSHA-256ANDMGF1PADDING",
+ "name": "RSA/NONE/OAEPwithSHA-256andMGF1Padding",
"supported_api_levels": "10+"
},
{
- "name": "RSA/NONE/OAEPWITHSHA-384ANDMGF1PADDING",
+ "name": "RSA/NONE/OAEPwithSHA-384andMGF1Padding",
"supported_api_levels": "23+"
},
{
- "name": "RSA/NONE/OAEPWITHSHA-512ANDMGF1PADDING",
+ "name": "RSA/NONE/OAEPwithSHA-512andMGF1Padding",
"supported_api_levels": "23+"
},
{
- "name": "RSA/NONE/PKCS1PADDING",
+ "name": "RSA/NONE/PKCS1Padding",
"supported_api_levels": "1+"
}
],
@@ -628,36 +628,36 @@
"supported_api_levels": "1+"
},
{
- "name": "DESEDE",
+ "name": "DESede",
"supported_api_levels": "1+"
},
{
"deprecated": "true",
- "name": "DESEDEWRAP",
+ "name": "DESedeWRAP",
"supported_api_levels": "1-8"
},
{
- "name": "HMACMD5",
+ "name": "HmacMD5",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA1",
+ "name": "HmacSHA1",
"supported_api_levels": "11+"
},
{
- "name": "HMACSHA224",
+ "name": "HmacSHA224",
"supported_api_levels": "1-8,22+"
},
{
- "name": "HMACSHA256",
+ "name": "HmacSHA256",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA384",
+ "name": "HmacSHA384",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA512",
+ "name": "HmacSHA512",
"supported_api_levels": "1+"
},
{
@@ -701,11 +701,11 @@
{
"algorithms": [
{
- "name": "ANDROIDCASTORE",
+ "name": "AndroidCAStore",
"supported_api_levels": "14+"
},
{
- "name": "ANDROIDKEYSTORE",
+ "name": "AndroidKeyStore",
"supported_api_levels": "18+"
},
{
@@ -718,7 +718,7 @@
"supported_api_levels": "1+"
},
{
- "name": "BOUNCYCASTLE",
+ "name": "BouncyCastle",
"supported_api_levels": "1+"
},
{
@@ -737,21 +737,6 @@
"algorithms": [
{
"deprecated": "true",
- "name": "DESEDEMAC",
- "supported_api_levels": "1-8"
- },
- {
- "deprecated": "true",
- "name": "DESEDEMAC/CFB8",
- "supported_api_levels": "1-8"
- },
- {
- "deprecated": "true",
- "name": "DESEDEMAC64",
- "supported_api_levels": "1-8"
- },
- {
- "deprecated": "true",
"name": "DESMAC",
"supported_api_levels": "1-8"
},
@@ -762,31 +747,46 @@
},
{
"deprecated": "true",
- "name": "DESWITHISO9797",
+ "name": "DESedeMAC",
"supported_api_levels": "1-8"
},
{
- "name": "HMACMD5",
+ "deprecated": "true",
+ "name": "DESedeMAC/CFB8",
+ "supported_api_levels": "1-8"
+ },
+ {
+ "deprecated": "true",
+ "name": "DESedeMAC64",
+ "supported_api_levels": "1-8"
+ },
+ {
+ "deprecated": "true",
+ "name": "DESwithISO9797",
+ "supported_api_levels": "1-8"
+ },
+ {
+ "name": "HmacMD5",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA1",
+ "name": "HmacSHA1",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA224",
+ "name": "HmacSHA224",
"supported_api_levels": "1-8,22+"
},
{
- "name": "HMACSHA256",
+ "name": "HmacSHA256",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA384",
+ "name": "HmacSHA384",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA512",
+ "name": "HmacSHA512",
"supported_api_levels": "1+"
},
{
@@ -795,27 +795,27 @@
"supported_api_levels": "1-8"
},
{
- "name": "PBEWITHHMACSHA",
+ "name": "PBEwithHmacSHA",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHHMACSHA1",
+ "name": "PBEwithHmacSHA1",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHHMACSHA224",
+ "name": "PBEwithHmacSHA224",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256",
+ "name": "PBEwithHmacSHA256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384",
+ "name": "PBEwithHmacSHA384",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512",
+ "name": "PBEwithHmacSHA512",
"supported_api_levels": "26+"
}
],
@@ -853,7 +853,7 @@
{
"algorithms": [
{
- "name": "DEFAULT",
+ "name": "Default",
"supported_api_levels": "10+"
},
{
@@ -862,7 +862,7 @@
},
{
"deprecated": "true",
- "name": "SSLV3",
+ "name": "SSLv3",
"supported_api_levels": "10-25"
},
{
@@ -870,15 +870,15 @@
"supported_api_levels": "1+"
},
{
- "name": "TLSV1",
+ "name": "TLSv1",
"supported_api_levels": "10+"
},
{
- "name": "TLSV1.1",
+ "name": "TLSv1.1",
"supported_api_levels": "16+"
},
{
- "name": "TLSV1.2",
+ "name": "TLSv1.2",
"supported_api_levels": "16+"
}
],
@@ -895,175 +895,175 @@
"supported_api_levels": "1+"
},
{
- "name": "DESEDE",
+ "name": "DESede",
"supported_api_levels": "1+"
},
{
- "name": "HMACSHA1",
+ "name": "HmacSHA1",
"supported_api_levels": "23+"
},
{
- "name": "HMACSHA224",
+ "name": "HmacSHA224",
"supported_api_levels": "23+"
},
{
- "name": "HMACSHA256",
+ "name": "HmacSHA256",
"supported_api_levels": "23+"
},
{
- "name": "HMACSHA384",
+ "name": "HmacSHA384",
"supported_api_levels": "23+"
},
{
- "name": "HMACSHA512",
+ "name": "HmacSHA512",
"supported_api_levels": "23+"
},
{
- "name": "PBEWITHHMACSHA1",
+ "name": "PBEwithHmacSHA1",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHHMACSHA1ANDAES_128",
+ "name": "PBEwithHmacSHA1AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA1ANDAES_256",
+ "name": "PBEwithHmacSHA1AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA224ANDAES_128",
+ "name": "PBEwithHmacSHA224AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA224ANDAES_256",
+ "name": "PBEwithHmacSHA224AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256ANDAES_128",
+ "name": "PBEwithHmacSHA256AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA256ANDAES_256",
+ "name": "PBEwithHmacSHA256AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384ANDAES_128",
+ "name": "PBEwithHmacSHA384AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA384ANDAES_256",
+ "name": "PBEwithHmacSHA384AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512ANDAES_128",
+ "name": "PBEwithHmacSHA512AndAES_128",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHHMACSHA512ANDAES_256",
+ "name": "PBEwithHmacSHA512AndAES_256",
"supported_api_levels": "26+"
},
{
- "name": "PBEWITHMD5AND128BITAES-CBC-OPENSSL",
+ "name": "PBEwithMD5AND128BITAES-CBC-OPENSSL",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHMD5AND192BITAES-CBC-OPENSSL",
+ "name": "PBEwithMD5AND192BITAES-CBC-OPENSSL",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHMD5AND256BITAES-CBC-OPENSSL",
+ "name": "PBEwithMD5AND256BITAES-CBC-OPENSSL",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHMD5ANDDES",
+ "name": "PBEwithMD5ANDDES",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHMD5ANDRC2",
+ "name": "PBEwithMD5ANDRC2",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA1ANDDES",
+ "name": "PBEwithSHA1ANDDES",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA1ANDRC2",
+ "name": "PBEwithSHA1ANDRC2",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA256AND128BITAES-CBC-BC",
+ "name": "PBEwithSHA256AND128BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA256AND192BITAES-CBC-BC",
+ "name": "PBEwithSHA256AND192BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHA256AND256BITAES-CBC-BC",
+ "name": "PBEwithSHA256AND256BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND128BITAES-CBC-BC",
+ "name": "PBEwithSHAAND128BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND128BITRC2-CBC",
+ "name": "PBEwithSHAAND128BITRC2-CBC",
"supported_api_levels": "10+"
},
{
- "name": "PBEWITHSHAAND128BITRC4",
+ "name": "PBEwithSHAAND128BITRC4",
"supported_api_levels": "10+"
},
{
- "name": "PBEWITHSHAAND192BITAES-CBC-BC",
+ "name": "PBEwithSHAAND192BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND2-KEYTRIPLEDES-CBC",
+ "name": "PBEwithSHAAND2-KEYTRIPLEDES-CBC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND256BITAES-CBC-BC",
+ "name": "PBEwithSHAAND256BITAES-CBC-BC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND3-KEYTRIPLEDES-CBC",
+ "name": "PBEwithSHAAND3-KEYTRIPLEDES-CBC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND40BITRC2-CBC",
+ "name": "PBEwithSHAAND40BITRC2-CBC",
"supported_api_levels": "1+"
},
{
- "name": "PBEWITHSHAAND40BITRC4",
+ "name": "PBEwithSHAAND40BITRC4",
"supported_api_levels": "10+"
},
{
- "name": "PBEWITHSHAANDTWOFISH-CBC",
+ "name": "PBEwithSHAANDTWOFISH-CBC",
"supported_api_levels": "10+"
},
{
- "name": "PBKDF2WITHHMACSHA1",
+ "name": "PBKDF2withHmacSHA1",
"supported_api_levels": "10+"
},
{
- "name": "PBKDF2WITHHMACSHA1AND8BIT",
+ "name": "PBKDF2withHmacSHA1And8BIT",
"supported_api_levels": "19+"
},
{
- "name": "PBKDF2WITHHMACSHA224",
+ "name": "PBKDF2withHmacSHA224",
"supported_api_levels": "26+"
},
{
- "name": "PBKDF2WITHHMACSHA256",
+ "name": "PBKDF2withHmacSHA256",
"supported_api_levels": "26+"
},
{
- "name": "PBKDF2WITHHMACSHA384",
+ "name": "PBKDF2withHmacSHA384",
"supported_api_levels": "26+"
},
{
- "name": "PBKDF2WITHHMACSHA512",
+ "name": "PBKDF2withHmacSHA512",
"supported_api_levels": "26+"
}
],
@@ -1085,7 +1085,7 @@
"supported_api_levels": "1+"
},
{
- "name": "DSAWITHSHA1",
+ "name": "DSAwithSHA1",
"supported_api_levels": "1+"
},
{
@@ -1098,38 +1098,38 @@
"supported_api_levels": "11+"
},
{
- "name": "ECDSAWITHSHA1",
+ "name": "ECDSAwithSHA1",
"supported_api_levels": "11+"
},
{
"deprecated": "true",
- "name": "MD2WITHRSA",
+ "name": "MD2withRSA",
"supported_api_levels": "1-3"
},
{
"deprecated": "true",
- "name": "MD4WITHRSA",
+ "name": "MD4withRSA",
"supported_api_levels": "1-8"
},
{
- "name": "MD5WITHRSA",
+ "name": "MD5withRSA",
"supported_api_levels": "1+"
},
{
"deprecated": "true",
- "name": "MD5WITHRSA/ISO9796-2",
+ "name": "MD5withRSA/ISO9796-2",
"supported_api_levels": "1-8"
},
{
- "name": "NONEWITHDSA",
+ "name": "NONEwithDSA",
"supported_api_levels": "1+"
},
{
- "name": "NONEWITHECDSA",
+ "name": "NONEwithECDSA",
"supported_api_levels": "11+"
},
{
- "name": "NONEWITHRSA",
+ "name": "NONEwithRSA",
"supported_api_levels": "17+"
},
{
@@ -1138,80 +1138,80 @@
"supported_api_levels": "1-8"
},
{
- "name": "SHA1WITHDSA",
+ "name": "SHA1withDSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA1WITHECDSA",
+ "name": "SHA1withECDSA",
"supported_api_levels": "11+"
},
{
- "name": "SHA1WITHRSA",
+ "name": "SHA1withRSA",
"supported_api_levels": "1+"
},
{
"deprecated": "true",
- "name": "SHA1WITHRSA/ISO9796-2",
+ "name": "SHA1withRSA/ISO9796-2",
"supported_api_levels": "1-8"
},
{
- "name": "SHA1WITHRSA/PSS",
+ "name": "SHA1withRSA/PSS",
"supported_api_levels": "23+"
},
{
- "name": "SHA224WITHDSA",
+ "name": "SHA224withDSA",
"supported_api_levels": "20+"
},
{
- "name": "SHA224WITHECDSA",
+ "name": "SHA224withECDSA",
"supported_api_levels": "20+"
},
{
- "name": "SHA224WITHRSA",
+ "name": "SHA224withRSA",
"supported_api_levels": "20+"
},
{
- "name": "SHA224WITHRSA/PSS",
+ "name": "SHA224withRSA/PSS",
"supported_api_levels": "23+"
},
{
- "name": "SHA256WITHDSA",
+ "name": "SHA256withDSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA256WITHECDSA",
+ "name": "SHA256withECDSA",
"supported_api_levels": "11+"
},
{
- "name": "SHA256WITHRSA",
+ "name": "SHA256withRSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA256WITHRSA/PSS",
+ "name": "SHA256withRSA/PSS",
"supported_api_levels": "23+"
},
{
- "name": "SHA384WITHECDSA",
+ "name": "SHA384withECDSA",
"supported_api_levels": "11+"
},
{
- "name": "SHA384WITHRSA",
+ "name": "SHA384withRSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA384WITHRSA/PSS",
+ "name": "SHA384withRSA/PSS",
"supported_api_levels": "23+"
},
{
- "name": "SHA512WITHECDSA",
+ "name": "SHA512withECDSA",
"supported_api_levels": "11+"
},
{
- "name": "SHA512WITHRSA",
+ "name": "SHA512withRSA",
"supported_api_levels": "1+"
},
{
- "name": "SHA512WITHRSA/PSS",
+ "name": "SHA512withRSA/PSS",
"supported_api_levels": "23+"
}
],
@@ -1227,5 +1227,5 @@
"name": "TrustManagerFactory"
}
],
- "last_updated": "2017-03-16 12:35:47 UTC"
+ "last_updated": "2017-03-21 16:04:30 UTC"
}
\ No newline at end of file
diff --git a/tools/docs/crypto/format_supported_algorithm_table.py b/tools/docs/crypto/format_supported_algorithm_table.py
index 1460099..3b23066 100755
--- a/tools/docs/crypto/format_supported_algorithm_table.py
+++ b/tools/docs/crypto/format_supported_algorithm_table.py
@@ -20,8 +20,8 @@
reflect the crypto algorithm support shown in the provided data file.
"""
+import argparse
import operator
-import sys
import crypto_docs
@@ -31,18 +31,24 @@
def main():
- if len(sys.argv) < 2:
- print 'Must supply argument to data file.'
- sys.exit(1)
- data = crypto_docs.load_json(sys.argv[1])
+ parser = argparse.ArgumentParser(description='Output algorithm support HTML tables')
+ parser.add_argument('--for_javadoc',
+ action='store_true',
+ help='If specified, format for inclusion in class documentation')
+ parser.add_argument('file',
+ help='The JSON file to use for data')
+ args = parser.parse_args()
+
+ output = []
+ data = crypto_docs.load_json(args.file)
categories = sort_by_name(data['categories'])
- print '<h2 id="SupportedAlgorithms">Supported Algorithms</h2>'
- print
- print '<ul>'
+ output.append('<h2 id="SupportedAlgorithms">Supported Algorithms</h2>')
+ output.append('')
+ output.append('<ul>')
for category in categories:
- print (' <li><a href="#Supported{name}">'
+ output.append(' <li><a href="#Supported{name}">'
'<code>{name}</code></a></li>'.format(**category))
- print '</ul>'
+ output.append('</ul>')
for category in categories:
if category['name'] == 'Cipher':
# We display ciphers in a four-column table to conserve space and
@@ -90,16 +96,17 @@
i += 1
# Display the table with rowspans for those entries where all the
# items have the same algorithm, mode, etc
- print '''
-<h3 id="Supported{name}">{name}</h3>
-<table>
- <thead>
- <th>Algorithm</th>
- <th>Modes</th>
- <th>Paddings</th>
- <th>Supported API Levels</th>
- </thead>
- <tbody>'''.format(**category)
+ output.append('<h3 id="Supported{name}">{name}</h3>'.format(**category))
+ output.append('<table>')
+ output.append(' <thead>')
+ output.append(' <tr>')
+ output.append(' <th>Algorithm</th>')
+ output.append(' <th>Modes</th>')
+ output.append(' <th>Paddings</th>')
+ output.append(' <th>Supported API Levels</th>')
+ output.append(' </tr>')
+ output.append(' </thead>')
+ output.append(' <tbody>')
tuples.sort(key=operator.itemgetter(0, 4, 1, 2, 3))
i = 0
cur_deprecated = None
@@ -112,9 +119,9 @@
cur_algorithm = None
cur_mode = None
if cur_deprecated:
- print ' <tr class="deprecated">'
+ output.append(' <tr class="deprecated">')
else:
- print ' <tr>'
+ output.append(' <tr>')
if row[0] != cur_algorithm:
cur_algorithm = row[0]
cur_mode = None
@@ -125,9 +132,9 @@
j += 1
rowspan = j - i
if rowspan > 1:
- print ' <td rowspan="%d">%s</td>' % (rowspan, cur_algorithm)
+ output.append(' <td rowspan="%d">%s</td>' % (rowspan, cur_algorithm))
else:
- print ' <td>%s</td>' % cur_algorithm
+ output.append(' <td>%s</td>' % cur_algorithm)
if row[1] != cur_mode:
cur_mode = row[1]
j = i + 1
@@ -139,38 +146,40 @@
rowspan = j - i
modestring = '<br>'.join(cur_mode)
if rowspan > 1:
- print ' <td rowspan="%d">%s</td>' % (rowspan, modestring)
+ output.append(' <td rowspan="%d">%s</td>' % (rowspan, modestring))
else:
- print ' <td>%s</td>' % modestring
- print ' <td>%s</td>' % '<br>'.join(row[2])
- print ' <td>%s</td>' % row[3]
- print ' </tr>'
+ output.append(' <td>%s</td>' % modestring)
+ output.append(' <td>%s</td>' % '<br>'.join(row[2]))
+ output.append(' <td>%s</td>' % row[3])
+ output.append(' </tr>')
i += 1
- print '''
- </tbody>
-</table>'''
+ output.append(' </tbody>')
+ output.append('</table>')
else:
- print '''
-<h3 id="Supported{name}">{name}</h3>
-<table>
- <thead>
- <th>Algorithm</th>
- <th>Supported API Levels</th>
- </thead>
- <tbody>'''.format(**category)
+ output.append('<h3 id="Supported{name}">{name}</h3>'.format(**category))
+ output.append('<table>')
+ output.append(' <thead>')
+ output.append(' <tr>')
+ output.append(' <th>Algorithm</th>')
+ output.append(' <th>Supported API Levels</th>')
+ output.append(' </tr>')
+ output.append(' </thead>')
+ output.append(' <tbody>')
algorithms = sort_by_name(category['algorithms'])
for algorithm in algorithms:
- dep_class = ''
if 'deprecated' in algorithm and algorithm['deprecated']:
- dep_class = ' class="deprecated"'
- print '''
- <tr{deprecated_class}>
- <td>{name}</td>
- <td>{supported_api_levels}</td>
- </tr>'''.format(deprecated_class=dep_class, **algorithm)
- print '''
- </tbody>
-</table>'''
+ output.append(' <tr class="deprecated">')
+ else:
+ output.append(' <tr>')
+ output.append(' <td>{name}</td>'.format(**algorithm))
+ output.append(' <td>{supported_api_levels}</td>'.format(**algorithm))
+ output.append(' </tr>')
+ output.append(' </tbody>')
+ output.append('</table>')
+ if args.for_javadoc:
+ for i in range(len(output)):
+ output[i] = ' * ' + output[i]
+ print '\n'.join(output)
if __name__ == '__main__':
diff --git a/tools/docs/crypto/update_crypto_support.py b/tools/docs/crypto/update_crypto_support.py
index 8d39cf8..207e0f4 100755
--- a/tools/docs/crypto/update_crypto_support.py
+++ b/tools/docs/crypto/update_crypto_support.py
@@ -24,9 +24,9 @@
import argparse
import collections
-import copy
import datetime
import json
+import re
import sys
import crypto_docs
@@ -63,6 +63,14 @@
return None
+def find_by_normalized_name(seq, name):
+ """Returns the first element in seq with the given normalized name."""
+ for item in seq:
+ if normalize_name(item['name']) == name:
+ return item
+ return None
+
+
def sort_by_name(seq):
"""Returns a copy of the input sequence sorted by name."""
return sorted(seq, key=lambda x: x['name'])
@@ -84,6 +92,22 @@
return name
+def fix_name_caps_for_output(name):
+ """Returns a version of the given algorithm name with capitalization fixed."""
+ # It's important that this must only change the capitalization of the
+ # name, not any of its text, otherwise future runs won't be able to
+ # match this name with the name coming from the device.
+
+ # We current make the following capitalization fixes
+ # DESede (not DESEDE)
+ # FOOwithBAR (not FOOWITHBAR or FOOWithBAR)
+ # Hmac (not HMAC)
+ name = re.sub('WITH', 'with', name, flags=re.I)
+ name = re.sub('DESEDE', 'DESede', name, flags=re.I)
+ name = re.sub('HMAC', 'Hmac', name, flags=re.I)
+ return name
+
+
def get_current_data(f):
"""Returns a map of the algorithms in the given input.
@@ -95,12 +119,17 @@
The returned algorithms will have their names normalized.
+ Returns:
+ A dict of categories to lists of normalized algorithm names and a
+ dict of normalized algorithm names to original algorithm names.
+
Raises:
EOFError: If either the BEGIN or END sentinel lines are not present.
ValueError: If a line between the BEGIN and END sentinel lines is not
made up of two identifiers separated by whitespace.
"""
current_data = collections.defaultdict(list)
+ name_dict = {}
saw_begin = False
saw_end = False
@@ -116,7 +145,9 @@
category, algorithm = line.split()
if category not in SUPPORTED_CATEGORIES:
continue
- current_data[category].append(normalize_name(algorithm))
+ normalized_name = normalize_name(algorithm)
+ current_data[category].append(normalized_name)
+ name_dict[normalized_name] = algorithm
if not saw_begin:
raise EOFError(
@@ -124,10 +155,10 @@
if not saw_end:
raise EOFError(
'Reached the end of input without encountering the end sentinel')
- return dict(current_data)
+ return dict(current_data), name_dict
-def update_data(prev_data, current_data, api_level, date):
+def update_data(prev_data, current_data, name_dict, api_level, date):
"""Returns a copy of prev_data, modified to take into account current_data.
Updates the algorithm support metadata structure by starting with the
@@ -152,14 +183,20 @@
current_category = (
current_data[category] if category in current_data else [])
new_category = {'name': category, 'algorithms': []}
- prev_algorithms = [x['name'] for x in prev_category['algorithms']]
+ prev_algorithms = [normalize_name(x['name']) for x in prev_category['algorithms']]
alg_union = set(prev_algorithms) | set(current_category)
for alg in alg_union:
- new_algorithm = {'name': alg}
+ prev_alg = find_by_normalized_name(prev_category['algorithms'], alg)
+ if alg in name_dict:
+ new_algorithm = {'name': name_dict[alg]}
+ elif prev_alg is not None:
+ new_algorithm = {'name': prev_alg['name']}
+ else:
+ new_algorithm = {'name': alg}
+ new_algorithm['name'] = fix_name_caps_for_output(new_algorithm['name'])
new_level = None
if alg in current_category and alg in prev_algorithms:
# Both old and new have it, just ensure the API level is right
- prev_alg = find_by_name(prev_category['algorithms'], alg)
if prev_alg['supported_api_levels'].endswith('+'):
new_level = prev_alg['supported_api_levels']
else:
@@ -168,7 +205,6 @@
elif alg in prev_algorithms:
# Only in the old set, so ensure the API level is marked
# as ending
- prev_alg = find_by_name(prev_category['algorithms'], alg)
if prev_alg['supported_api_levels'].endswith('+'):
# The algorithm is newly missing, so modify the support
# to end at the previous level
@@ -210,10 +246,11 @@
prev_data = crypto_docs.load_json(args.file)
- current_data = get_current_data(sys.stdin)
+ current_data, name_dict = get_current_data(sys.stdin)
new_data = update_data(prev_data,
current_data,
+ name_dict,
args.api_level,
datetime.datetime.utcnow())
diff --git a/tools/docs/crypto/update_crypto_support_test.py b/tools/docs/crypto/update_crypto_support_test.py
index cb8fe87..4fbc210 100755
--- a/tools/docs/crypto/update_crypto_support_test.py
+++ b/tools/docs/crypto/update_crypto_support_test.py
@@ -20,10 +20,11 @@
import update_crypto_support
-def do_update_data(prev_data, current_data):
+def do_update_data(prev_data, current_data, name_dict={}):
return update_crypto_support.update_data(
prev_data,
current_data,
+ name_dict,
72,
datetime.datetime.utcfromtimestamp(1234567890))
@@ -88,8 +89,12 @@
OtherThing Mary
END ALGORITHM LIST
''')),
- {'Mac': ['BOB', 'JONES', 'AMY'],
- 'MessageDigest': ['JIM']})
+ ({'Mac': ['BOB', 'JONES', 'AMY'],
+ 'MessageDigest': ['JIM']},
+ {'AMY': 'Amy',
+ 'BOB': 'Bob',
+ 'JONES': 'Jones',
+ 'JIM': 'Jim'}))
self.assertEqual(update_crypto_support.get_current_data(
StringIO.StringIO(
'''
@@ -102,8 +107,12 @@
OtherThing Mary
END ALGORITHM LIST
''')),
- {'Mac': ['DUPE', 'JONES', 'AMY', 'DUPE'],
- 'MessageDigest': ['JIM']})
+ ({'Mac': ['DUPE', 'JONES', 'AMY', 'DUPE'],
+ 'MessageDigest': ['JIM']},
+ {'AMY': 'Amy',
+ 'DUPE': 'Dupe',
+ 'JONES': 'Jones',
+ 'JIM': 'Jim'}))
self.assertEqual(update_crypto_support.get_current_data(
StringIO.StringIO(
'''
@@ -117,8 +126,12 @@
END ALGORITHM LIST
Mac AlsoNotAValue
''')),
- {'Mac': ['BOB', 'JONES', 'AMY'],
- 'MessageDigest': ['JIM']})
+ ({'Mac': ['BOB', 'JONES', 'AMY'],
+ 'MessageDigest': ['JIM']},
+ {'AMY': 'Amy',
+ 'BOB': 'Bob',
+ 'JONES': 'Jones',
+ 'JIM': 'Jim'}))
self.assertEqual(update_crypto_support.get_current_data(
StringIO.StringIO(
'''
@@ -132,8 +145,12 @@
OtherThing Mary
END ALGORITHM LIST
''')),
- {'Mac': ['BOB', 'JONES', 'AMY'],
- 'MessageDigest': ['JIM']})
+ ({'Mac': ['BOB', 'JONES', 'AMY'],
+ 'MessageDigest': ['JIM']},
+ {'AMY': 'Amy',
+ 'BOB': 'Bob',
+ 'JONES': 'Jones',
+ 'JIM': 'Jim'}))
with self.assertRaises(EOFError):
update_crypto_support.get_current_data(StringIO.StringIO(
'''
@@ -342,6 +359,59 @@
'api_level': '72',
'last_updated': LAST_UPDATED_TEXT})
+ def test_update_name_matching(self):
+ self.assertEqual(
+ do_update_data(
+ {'categories': [
+ {'name': 'MessageDigest',
+ 'algorithms': [
+ {'name': 'sha-1',
+ 'supported_api_levels': '1+'},
+ {'name': 'Sha-2',
+ 'supported_api_levels': '1-22',
+ 'deprecated': 'true'},
+ {'name': 'SHA-3',
+ 'supported_api_levels': '7+'}]}]},
+ {'MessageDigest': ['SHA-1', 'SHA-2', 'SHA-3']},
+ {'SHA-1': 'Sha-1', 'SHA-2': 'Sha-2', 'SHA-3': 'Sha-3'}),
+ {'categories': [
+ {'name': 'MessageDigest',
+ 'algorithms': [
+ {'name': 'Sha-1',
+ 'supported_api_levels': '1+'},
+ {'name': 'Sha-2',
+ 'supported_api_levels': '1-22,72+'},
+ {'name': 'Sha-3',
+ 'supported_api_levels': '7+'}]}],
+ 'api_level': '72',
+ 'last_updated': LAST_UPDATED_TEXT})
+ self.assertEqual(
+ do_update_data(
+ {'categories': [
+ {'name': 'MessageDigest',
+ 'algorithms': [
+ {'name': 'sha-1',
+ 'supported_api_levels': '1+'},
+ {'name': 'Sha-2',
+ 'supported_api_levels': '1-22',
+ 'deprecated': 'true'},
+ {'name': 'SHA-3',
+ 'supported_api_levels': '7+'}]}]},
+ {'MessageDigest': ['SHA-1', 'SHA-3']},
+ {'SHA-1': 'Sha-1', 'SHA-3': 'Sha-3'}),
+ {'categories': [
+ {'name': 'MessageDigest',
+ 'algorithms': [
+ {'name': 'Sha-1',
+ 'supported_api_levels': '1+'},
+ {'name': 'Sha-2',
+ 'supported_api_levels': '1-22',
+ 'deprecated': 'true'},
+ {'name': 'Sha-3',
+ 'supported_api_levels': '7+'}]}],
+ 'api_level': '72',
+ 'last_updated': LAST_UPDATED_TEXT})
+
if __name__ == '__main__':
unittest.main()
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java b/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
index 52fa2b4..bb49fe0 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
+++ b/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
@@ -30,7 +30,7 @@
* A distro-validation / extraction class. Separate from the services code that uses it for easier
* testing. This class is not thread-safe: callers are expected to handle mutual exclusion.
*/
-public final class TimeZoneDistroInstaller {
+public class TimeZoneDistroInstaller {
/** {@link #installWithErrorCode(byte[])} result code: Success. */
public final static int INSTALL_SUCCESS = 0;
/** {@link #installWithErrorCode(byte[])} result code: Distro corrupt. */