Merge "Use System.nanoTime() for timeouts and durations"
diff --git a/Docs.mk b/Docs.mk
index 0c52bf5..a163d1f 100644
--- a/Docs.mk
+++ b/Docs.mk
@@ -20,20 +20,11 @@
libart/src/main/java/dalvik \
libart/src/main/java/java \
luni/src/main/java/android \
+ luni/src/main/java/java \
luni/src/main/java/javax \
luni/src/main/java/org/xml/sax \
luni/src/main/java/org/w3c \
xml/src/main/java/org/xmlpull/v1)
-# IcuIteratorWrapper.java references com.ibm.icu.text.BreakIterator,
-# which is renamed by our jarjar rule, and so unrecognizable by javadoc,
-# with annoying error: error: package com.ibm.icu.text does not exist.
-# We don't want to generate doc for this file anyway.
-libcore_to_document += \
- $(filter-out luni/src/main/java/java/text/IcuIteratorWrapper.java,\
- $(call find-files-in-subdirs, libcore, \
- "*.java", \
- luni/src/main/java/java))
-
libcore_docs_include_once := 1
endif # libcore_docs_include_once
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index fb0b207..8720170 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -77,10 +77,9 @@
icu4j_src_files := $(call all-java-files-under,$(icu4j_root)/main/classes)
# Filter out bits of ICU4J we don't use yet : the SPIs (which we have limited support for),
-# the charset encoders and the transliterators.
+# and the charset encoders
icu4j_src_files := $(filter-out $(icu4j_root)/main/classes/localespi/%, $(icu4j_src_files))
icu4j_src_files := $(filter-out $(icu4j_root)/main/classes/charset/%, $(icu4j_src_files))
-icu4j_src_files := $(filter-out $(icu4j_root)/main/classes/translit/%, $(icu4j_src_files))
# Not all src dirs contain resources, some instead contain other random files
# that should not be included as resources. The ones that should be included
@@ -93,7 +92,6 @@
icu4j_resource_dirs := $(call all-icu-subdir-with-subdir,$(icu4j_root)/main/classes/*/src,com/ibm/icu)
icu4j_resource_dirs := $(filter-out $(icu4j_root)/main/classes/localespi/%, $(icu4j_resource_dirs))
icu4j_resource_dirs := $(filter-out $(icu4j_root)/main/classes/charset/%, $(icu4j_resource_dirs))
-icu4j_resource_dirs := $(filter-out $(icu4j_root)/main/classes/translit/%, $(icu4j_resource_dirs))
@@ -122,7 +120,7 @@
LOCAL_SRC_FILES := $(test_src_files)
LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-libart okhttp core-junit bouncycastle
+LOCAL_JAVA_LIBRARIES := core-libart okhttp core-junit bouncycastle mockito-target
LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support sqlite-jdbc mockwebserver nist-pkix-tests
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE := core-tests
@@ -162,12 +160,6 @@
ifeq ($(HOST_OS),linux)
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-main-java-files-under, dex)
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := dex-host
-include $(BUILD_HOST_JAVA_LIBRARY)
-
# Definitions to make the core library.
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(libart_core_src_files) $(icu4j_src_files)
@@ -188,7 +180,7 @@
LOCAL_SRC_FILES := $(test_src_files)
LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
LOCAL_NO_STANDARD_LIBRARIES := true
- LOCAL_JAVA_LIBRARIES := core-libart-hostdex okhttp-hostdex bouncycastle-hostdex core-junit-hostdex core-tests-support-hostdex
+ LOCAL_JAVA_LIBRARIES := core-libart-hostdex okhttp-hostdex bouncycastle-hostdex core-junit-hostdex core-tests-support-hostdex mockito-api-hostdex
LOCAL_STATIC_JAVA_LIBRARIES := sqlite-jdbc-host mockwebserver-host nist-pkix-tests-host
LOCAL_JAVACFLAGS := $(local_javac_flags)
LOCAL_MODULE_TAGS := optional
diff --git a/benchmarks/src/benchmarks/regression/BidiBenchmark.java b/benchmarks/src/benchmarks/regression/BidiBenchmark.java
new file mode 100644
index 0000000..bb5087e
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/BidiBenchmark.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 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 benchmarks.regression;
+
+import com.google.caliper.SimpleBenchmark;
+
+import java.math.BigDecimal;
+import java.text.AttributedCharacterIterator;
+import java.text.Bidi;
+import java.text.DecimalFormat;
+
+public class BidiBenchmark extends SimpleBenchmark {
+
+ private static final AttributedCharacterIterator charIter =
+ DecimalFormat.getInstance().formatToCharacterIterator(new BigDecimal(Math.PI));
+
+ public void time_createBidiFromIter(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Bidi bidi = new Bidi(charIter);
+ }
+ }
+
+ public void time_createBidiFromCharArray(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Bidi bd = new Bidi(new char[]{'s', 's', 's'}, 0, new byte[]{(byte) 1,
+ (byte) 2, (byte) 3}, 0, 3, Bidi.DIRECTION_RIGHT_TO_LEFT);
+ }
+ }
+
+ public void time_createBidiFromString(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Bidi bidi = new Bidi("Hello", Bidi.DIRECTION_LEFT_TO_RIGHT);
+ }
+ }
+
+ public void time_reorderVisually(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Bidi.reorderVisually(new byte[]{2, 1, 3, 0, 4}, 0,
+ new String[]{"H", "e", "l", "l", "o"}, 0, 5);
+ }
+ }
+
+ public void time_hebrewBidi(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Bidi bd = new Bidi(new char[]{'\u05D0', '\u05D0', '\u05D0'}, 0,
+ new byte[]{(byte) -1, (byte) -2, (byte) -3}, 0, 3,
+ Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+ bd = new Bidi(new char[]{'\u05D0', '\u05D0', '\u05D0'}, 0,
+ new byte[]{(byte) -1, (byte) -2, (byte) -3}, 0, 3,
+ Bidi.DIRECTION_LEFT_TO_RIGHT);
+ }
+ }
+
+ public void time_complicatedOverrideBidi(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Bidi bd = new Bidi("a\u05D0a\"a\u05D0\"\u05D0a".toCharArray(), 0,
+ new byte[]{0, 0, 0, -3, -3, 2, 2, 0, 3}, 0, 9,
+ Bidi.DIRECTION_RIGHT_TO_LEFT);
+ }
+ }
+
+ public void time_requiresBidi(int reps) {
+ for (int i = 0; i < reps; i++) {
+ Bidi.requiresBidi("\u05D0".toCharArray(), 1, 1); // false.
+ Bidi.requiresBidi("\u05D0".toCharArray(), 0, 1); // true.
+ }
+ }
+
+}
diff --git a/benchmarks/src/benchmarks/regression/IdnBenchmark.java b/benchmarks/src/benchmarks/regression/IdnBenchmark.java
new file mode 100644
index 0000000..9de5261
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/IdnBenchmark.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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 benchmarks.regression;
+
+import com.google.caliper.SimpleBenchmark;
+
+import java.net.IDN;
+
+public class IdnBenchmark extends SimpleBenchmark {
+
+ public void timeToUnicode(int reps) {
+ for (int i = 0; i < reps; i++) {
+ IDN.toASCII("fass.de");
+ IDN.toASCII("faß.de");
+ IDN.toASCII("fäß.de");
+ IDN.toASCII("a\u200Cb");
+ IDN.toASCII("öbb.at");
+ IDN.toASCII("abc・日本.co.jp");
+ IDN.toASCII("日本.co.jp");
+ IDN.toASCII("x\u0327\u0301.de");
+ IDN.toASCII("σόλοσ.gr");
+ }
+ }
+
+ public void timeToAscii(int reps) {
+ for (int i = 0; i < reps; i++) {
+ IDN.toUnicode("xn--fss-qla.de");
+ IDN.toUnicode("xn--n00d.com");
+ IDN.toUnicode("xn--bb-eka.at");
+ IDN.toUnicode("xn--og-09a.de");
+ IDN.toUnicode("xn--53h.de");
+ IDN.toUnicode("xn--iny-zx5a.de");
+ IDN.toUnicode("xn--abc-rs4b422ycvb.co.jp");
+ IDN.toUnicode("xn--wgv71a.co.jp");
+ IDN.toUnicode("xn--x-xbb7i.de");
+ IDN.toUnicode("xn--wxaikc6b.gr");
+ IDN.toUnicode("xn--wxaikc6b.xn--gr-gtd9a1b0g.de");
+ }
+ }
+
+}
diff --git a/benchmarks/src/benchmarks/regression/ReflectionBenchmark.java b/benchmarks/src/benchmarks/regression/ReflectionBenchmark.java
index fcb2636..b1926f2 100644
--- a/benchmarks/src/benchmarks/regression/ReflectionBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/ReflectionBenchmark.java
@@ -163,6 +163,14 @@
}
}
+ public void timeClass_isInstance(int reps) throws Exception {
+ D d = new D();
+ Class<?> klass = IC.class;
+ for (int rep = 0; rep < reps; ++rep) {
+ klass.isInstance(d);
+ }
+ }
+
public void timeGetInstanceField(int reps) throws Exception {
for (int rep = 0; rep < reps; ++rep) {
// The field here (and in timeGetStaticField) were chosen to be
@@ -182,7 +190,6 @@
}
}
-
public static class C {
public static int sf = 0;
public int f = 0;
@@ -206,4 +213,16 @@
sf = value;
}
}
+
+ interface IA {
+ }
+
+ interface IB extends IA {
+ }
+
+ interface IC extends IB {
+ }
+
+ class D implements IC {
+ }
}
diff --git a/dalvik/src/main/java/dalvik/annotation/AndroidOnly.java b/dalvik/src/main/java/dalvik/annotation/AndroidOnly.java
deleted file mode 100644
index da3c1c5..0000000
--- a/dalvik/src/main/java/dalvik/annotation/AndroidOnly.java
+++ /dev/null
@@ -1,39 +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 dalvik.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Marks a test-case as Android-only, that is, it should not be executed on
- * other systems.
- *
- * @hide
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.METHOD, ElementType.TYPE })
-public @interface AndroidOnly {
-
- /**
- * Plain text reason for adding this annotation.
- */
- String value();
-
-}
diff --git a/dalvik/src/main/java/dalvik/annotation/BrokenTest.java b/dalvik/src/main/java/dalvik/annotation/BrokenTest.java
deleted file mode 100644
index 16788d0..0000000
--- a/dalvik/src/main/java/dalvik/annotation/BrokenTest.java
+++ /dev/null
@@ -1,40 +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 dalvik.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Marks a test case as broken. This means the test case should be fixed.
- *
- * @hide
- *
- * @deprecated - use expectations/brokentests.txt instead
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.METHOD })
-public @interface BrokenTest {
-
- /**
- * Plain text reason for adding this annotation.
- */
- String value();
-
-}
diff --git a/dalvik/src/main/java/dalvik/annotation/SideEffect.java b/dalvik/src/main/java/dalvik/annotation/SideEffect.java
deleted file mode 100644
index 2d691e3..0000000
--- a/dalvik/src/main/java/dalvik/annotation/SideEffect.java
+++ /dev/null
@@ -1,42 +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 dalvik.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Marks a test-case as either having a side-effect that other tests might
- * notice or suffering from such a side effect. Such tests should be run in an
- * isolated manner.
- *
- * @hide
- *
- * @deprecated - use expectations/brokentests.txt instead
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.METHOD, ElementType.TYPE })
-public @interface SideEffect {
-
- /**
- * Plain text reason for adding this annotation.
- */
- String value();
-
-}
diff --git a/dalvik/src/main/java/dalvik/annotation/TestLevel.java b/dalvik/src/main/java/dalvik/annotation/TestLevel.java
deleted file mode 100644
index f62ea2f..0000000
--- a/dalvik/src/main/java/dalvik/annotation/TestLevel.java
+++ /dev/null
@@ -1,85 +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 dalvik.annotation;
-
-/**
- * Defines an enumeration of possible states a test case can be in.
- *
- * @hide
- */
-public enum TestLevel {
-
- /**
- * Indicates that a test method completely tests its target API method.
- */
- COMPLETE,
-
- /**
- * Indicates that a test method partially tests its target API method and
- * that together with all other {@code PARTIAL_COMPLETE} tests for the same
- * method it is sufficient.
- */
- PARTIAL_COMPLETE,
-
- /**
- * Just for compatibility purposes, will be removed later.
- */
- PARTIAL_OK,
-
- /**
- * Indicates that a test method partially tests its target API method. It
- * needs a second review phase to find out if the sum of all partial tests
- * is sufficient for completely testing the target API method. If yes, the
- * level has to be changed to {@code PARTIAL_COMPLETE}.
- */
- PARTIAL,
-
- /**
- * Indicates that a test method is known to not completely test an API
- * method but the missing test steps are too complex and costly to
- * implement. This level is positioned somewhere between {@code PARTIAL}
- * and {@code COMPLETE}.
- */
- SUFFICIENT,
-
- /**
- * Indicates that a test method provides additional testing for an API
- * method for which there already exists one {@code COMPLETE} or a set of
- * {@code PARTIAL_COMPLETE} tests. This level may also be used for test
- * methods that test a concept which can not be directly attributed to
- * the specification of an API method or class.
- */
- ADDITIONAL,
-
- /**
- * Indicates that there is nothing to test in an API method, for example if
- * the specification states that a method does nothing.
- */
- NOT_NECESSARY,
-
- /**
- * Indicates that it is very hard or impossible to test an API method.
- */
- NOT_FEASIBLE,
-
- /**
- * Indicates that the tests is either insufficient or wrong. Something needs
- * to be done about it.
- */
- TODO,
-
-}
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java b/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java
index 1e16d0c..89116ba 100644
--- a/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java
+++ b/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java
@@ -38,10 +38,4 @@
* Specifies the class being tested.
*/
Class<?> value();
-
- /**
- * Option to specify untested methods for the class.
- * @hide
- */
- TestTargetNew[] untestedMethods() default {};
}
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java b/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
deleted file mode 100644
index 80aebee..0000000
--- a/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
+++ /dev/null
@@ -1,64 +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 dalvik.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Defines an annotation used be used within the TestInfo annotation. It
- * specifies a single method target for the test (but can be used multiple
- * times).
- * @hide
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
-public @interface TestTargetNew {
-
- /**
- * Specifies the name of the API method that is being tested. This field
- * may be left empty if the test target is a concept implemented in a
- * class rather than a concrete API method.
- */
- String method() default "";
-
- /**
- * Specifies the signature of the API method that is being tested, in terms
- * of Java classes.
- */
- Class<?>[] args() default {};
-
- /**
- * Specifies the class to which the tested method belongs. If this value is
- * not provided, the class identified in @TestTargetClass is used by the
- * test progress doclet.
- */
- Class<?> clazz() default void.class;
-
- /**
- * Specifies the level of coverage the tested API method has.
- */
- TestLevel level();
-
- /**
- * Specifies noteworthy plain-text information about the test, for example
- * if something is NOT covered by the test method.
- */
- String notes() default "";
-}
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTargets.java b/dalvik/src/main/java/dalvik/annotation/TestTargets.java
deleted file mode 100644
index 207572c..0000000
--- a/dalvik/src/main/java/dalvik/annotation/TestTargets.java
+++ /dev/null
@@ -1,39 +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 dalvik.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Defines an annotation for test classes that allows to link them to the class
- * that is being tested. The current assumption is that the test are somewhat
- * organized according to the API classes they test. Might be too strict for
- * some cases.
- * @hide
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.METHOD })
-public @interface TestTargets {
-
- /**
- * Specifies the API methods that are tested by the annotated test method.
- */
- TestTargetNew[] value();
-}
diff --git a/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java b/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java
deleted file mode 100644
index 751a038..0000000
--- a/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java
+++ /dev/null
@@ -1,43 +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 dalvik.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Defines an annotation for test methods that indicate the test method
- * need to be fixed in future.
- * {@hide pending API Council approval}
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.METHOD })
-public @interface ToBeFixed {
-
- /**
- * Specifies the related bug number on CTS bug tracking system.
- */
- String bug() default "";
-
- /**
- * Specifies why this method need to be fixed. If we think it's a bug, explain
- * the expectation and the actual result.
- */
- String explanation() default "";
-}
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index 59e28e2..23d7407 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -361,6 +361,8 @@
/**
* Counts the instances of a class.
+ * It is the caller's responsibility to do GC if they don't want unreachable
+ * objects to get counted.
*
* @param klass the class to be counted.
* @param assignable if false, direct instances of klass are
@@ -372,6 +374,21 @@
public static native long countInstancesOfClass(Class klass, boolean assignable);
/**
+ * Counts the instances of classes.
+ * It is the caller's responsibility to do GC if they don't want unreachable
+ * objects to get counted.
+ *
+ * @param classes the classes to be counted.
+ * @param assignable if false, direct instances of klass are
+ * counted. If true, instances that are
+ * assignable to klass, as defined by
+ * {@link Class#isAssignableFrom} are counted.
+ * @return an array containing the number of matching instances. The value for
+ * an index is the number of instances of the class at that index in number classes.
+ */
+ public static native long[] countInstancesOfClasses(Class[] classes, boolean assignable);
+
+ /**
* Export the heap per-space stats for dumpsys meminfo.
*
* The content of the array is:
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index f5a13c6..e903cbb 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -1526,5 +1526,14 @@
"com.android.org.conscrypt.NativeCryptoTest#test_SSL_renegotiate",
"com.android.org.conscrypt.NativeCryptoTest#test_SSL_do_handshake_clientCertificateRequested_throws_after_renegotiate"
]
+},
+{
+ description: "Failures in OldSHA1PRNGSecureRandomTest",
+ result: EXEC_FAILED,
+ names: [
+ "org.apache.harmony.tests.javax.security.OldSHA1PRNGSecureRandomTest#testNextBytesbyteArray02",
+ "org.apache.harmony.tests.javax.security.OldSHA1PRNGSecureRandomTest#testNextBytesbyteArray04",
+ "org.apache.harmony.tests.javax.security.OldSHA1PRNGSecureRandomTest#testSetSeedbyteArray03"
+ ]
}
]
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Process2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Process2Test.java
index 649488c..7294bdd 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Process2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/Process2Test.java
@@ -17,8 +17,6 @@
package org.apache.harmony.tests.java.lang;
-import dalvik.annotation.AndroidOnly;
-
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
@@ -35,7 +33,6 @@
* java.lang.Process#getOutputStream()
* Tests if these methods return buffered streams.
*/
- @AndroidOnly("dalvikvm specific")
public void test_streams()
throws IOException, InterruptedException {
Process p = javaProcessBuilder().start();
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericSignatureFormatErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericSignatureFormatErrorTest.java
index 0cad681..20b9ab0 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericSignatureFormatErrorTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/GenericSignatureFormatErrorTest.java
@@ -1,6 +1,5 @@
package org.apache.harmony.tests.java.lang.reflect;
-import dalvik.annotation.AndroidOnly;
import dalvik.system.DexFile;
import junit.framework.TestCase;
@@ -31,8 +30,6 @@
}
- @AndroidOnly("Uses Android specific class dalvik.system.DexFile " +
- "for loading classes.")
// SideEffect: strange issue (exception: 'could not open dex file',
// dalvikvm: 'waitpid failed' log msg - only occurs when @SideEffect is removed
// and this test is run via running tests.luni.AllTestsLang TestSuite
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SinkChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SinkChannelTest.java
index 32f59c5..55a8fc3 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SinkChannelTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/SinkChannelTest.java
@@ -463,7 +463,8 @@
public void test_socketChannel_read_close() throws Exception {
ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999));
+ ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(), 0 /* any free port */));
+ int localPort = ssc.socket().getLocalPort();
SocketChannel sc = SocketChannel.open();
ByteBuffer buf = null;
try{
@@ -472,7 +473,7 @@
}catch (NullPointerException e){
// expected
}
- sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999));
+ sc.connect(new InetSocketAddress(InetAddress.getLocalHost(), localPort));
SocketChannel sock = ssc.accept();
ssc.close();
sc.close();
@@ -487,9 +488,10 @@
public void test_socketChannel_read_write() throws Exception {
ServerSocketChannel ssc = ServerSocketChannel.open();
- ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999));
+ ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(), 0 /* any free port */));
+ int localPort = ssc.socket().getLocalPort();
SocketChannel sc = SocketChannel.open();
- sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999));
+ sc.connect(new InetSocketAddress(InetAddress.getLocalHost(), localPort));
SocketChannel sock = ssc.accept();
ByteBuffer[] buf = {ByteBuffer.allocate(10),null};
try {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumMapTest.java
index 676e373..b201468 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumMapTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/EnumMapTest.java
@@ -16,8 +16,6 @@
package org.apache.harmony.tests.java.util;
-import dalvik.annotation.AndroidOnly;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
@@ -333,7 +331,7 @@
/**
* java.util.EnumMap#entrySet()
*/
- @AndroidOnly("Map.Entry is indirectly modified on RI when Iterator.next() is invoked")
+ // AndroidOnly("Map.Entry is indirectly modified on RI when Iterator.next() is invoked")
@SuppressWarnings({ "unchecked", "boxing" })
public void test_entrySet() {
EnumMap enumSizeMap = new EnumMap(Size.class);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java
index c0e814e..87e177f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java
@@ -152,6 +152,8 @@
private TimeZone defaultTimeZone;
+ private Locale defaultLocale;
+
/**
* java.util.Formatter#Formatter()
*/
@@ -4164,6 +4166,7 @@
* test the short name for timezone whether uses DaylightTime or not
*/
public void test_DaylightTime() {
+ Locale.setDefault(Locale.US);
Calendar c1 = new GregorianCalendar(2007, 0, 1);
Calendar c2 = new GregorianCalendar(2007, 7, 1);
@@ -4216,6 +4219,8 @@
secret = File.createTempFile("secret", null);
+ defaultLocale = Locale.getDefault();
+
defaultTimeZone = TimeZone.getDefault();
TimeZone cst = TimeZone.getTimeZone("Asia/Shanghai");
TimeZone.setDefault(cst);
@@ -4239,6 +4244,7 @@
secret.delete();
}
+ Locale.setDefault(defaultLocale);
TimeZone.setDefault(defaultTimeZone);
}
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/GregorianCalendarTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/GregorianCalendarTest.java
index f35be4b..6f25495 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/GregorianCalendarTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/GregorianCalendarTest.java
@@ -31,6 +31,20 @@
private static final TimeZone AMERICA_CHICAGO = TimeZone.getTimeZone("America/Chicago");
private static final TimeZone AMERICA_NEW_YORK = TimeZone.getTimeZone("America/New_York");
+ private Locale defaultLocale;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ defaultLocale = Locale.getDefault();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ Locale.setDefault(defaultLocale);
+ super.tearDown();
+ }
+
/**
* java.util.GregorianCalendar#GregorianCalendar()
*/
@@ -531,6 +545,8 @@
* java.util.GregorianCalendar#roll(int, boolean)
*/
public void test_rollIZ() {
+ Locale.setDefault(Locale.US);
+
// Test for method void java.util.GregorianCalendar.roll(int, boolean)
GregorianCalendar gc = new GregorianCalendar(1972, Calendar.OCTOBER,
13, 19, 9, 59);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RandomTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RandomTest.java
index d51d8abf..f790a31 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RandomTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/RandomTest.java
@@ -18,12 +18,13 @@
package org.apache.harmony.tests.java.util;
import java.io.Serializable;
+import java.util.Arrays;
import java.util.Random;
import org.apache.harmony.testframework.serialization.SerializationTest;
public class RandomTest extends junit.framework.TestCase {
- Random r;
+ private Random r;
/**
* java.util.Random#Random()
@@ -44,6 +45,17 @@
.nextInt() == r2.nextInt());
}
+ public void test_setSeed() {
+ Random r = new Random();
+ r.setSeed(1337);
+ Random r2 = new Random();
+ r2.setSeed(1337);
+ for (int i = 0; i < 100; i++)
+ assertTrue("Values from randoms with same seed don't match", r
+ .nextInt() == r2.nextInt());
+ }
+
+
/**
* java.util.Random#nextBoolean()
*/
@@ -216,38 +228,39 @@
*/
public void test_setSeedJ() {
// Test for method void java.util.Random.setSeed(long)
- long[] randomArray = new long[100];
- boolean someDifferent = false;
- final long firstSeed = 1000;
- long aLong, anotherLong, yetAnotherLong;
- Random aRandom = new Random();
- Random anotherRandom = new Random();
- Random yetAnotherRandom = new Random();
- aRandom.setSeed(firstSeed);
- anotherRandom.setSeed(firstSeed);
- for (int counter = 0; counter < randomArray.length; counter++) {
- aLong = aRandom.nextLong();
- anotherLong = anotherRandom.nextLong();
- assertTrue(
- "Two randoms with same seeds gave differing nextLong values",
- aLong == anotherLong);
- yetAnotherLong = yetAnotherRandom.nextLong();
- randomArray[counter] = aLong;
- if (aLong != yetAnotherLong)
- someDifferent = true;
+ long[] random1Values = new long[100];
+ long[] random2Values = new long[100];
+ long[] random3Values = new long[100];
+
+ Random random1 = new Random();
+ Random random2 = new Random();
+ Random random3 = new Random();
+
+ random1.setSeed(1337);
+ random2.setSeed(1337);
+ random3.setSeed(5000);
+
+ for (int i = 0; i < 100; ++i) {
+ random1Values[i] = random1.nextLong();
+ random2Values[i] = random2.nextLong();
+ random3Values[i] = random3.nextLong();
}
- assertTrue(
- "Two randoms with the different seeds gave the same chain of values",
- someDifferent);
- aRandom.setSeed(firstSeed);
- for (int counter = 0; counter < randomArray.length; counter++)
- assertTrue(
- "Reseting a random to its old seed did not result in the same chain of values as it gave before",
- aRandom.nextLong() == randomArray[counter]);
+
+ assertTrue(Arrays.equals(random1Values, random2Values));
+ assertFalse(Arrays.equals(random2Values, random3Values));
+
+ // Set random3's seed to 1337 and assert it results in the same sequence of
+ // values as the first two randoms.
+ random3.setSeed(1337);
+ for (int i = 0; i < 100; ++i) {
+ random3Values[i] = random3.nextLong();
+ }
+
+ assertTrue(Arrays.equals(random1Values, random3Values));
}
- class Mock_Random extends Random {
- boolean nextCalled = false;
+ static final class Mock_Random extends Random {
+ private boolean nextCalled = false;
public boolean getFlag () {
boolean retVal = nextCalled;
@@ -283,18 +296,12 @@
assertTrue(mr.getFlag());
}
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
+ @Override
protected void setUp() {
r = new Random();
}
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
+ @Override
protected void tearDown() {
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarEntryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarEntryTest.java
index a48bd60..3f4ed3b 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarEntryTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarEntryTest.java
@@ -26,6 +26,7 @@
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import junit.framework.TestCase;
+import libcore.io.Streams;
import tests.support.resource.Support_Resources;
public class JarEntryTest extends TestCase {
@@ -80,9 +81,6 @@
}
}
- /**
- * java.util.jar.JarEntry#JarEntry(java.util.zip.ZipEntry)
- */
public void test_ConstructorLjava_util_zip_ZipEntry() {
assertNotNull("Jar file is null", jarFile);
zipEntry = jarFile.getEntry(entryName);
@@ -116,38 +114,46 @@
attrJar.close();
}
- /**
- * java.util.jar.JarEntry#getCertificates()
- */
- public void test_getCertificates() throws Exception {
+ // http://b/1864326
+ public void testCertificatesAndCodesigners() throws Exception {
zipEntry = jarFile.getEntry(entryName2);
jarEntry = new JarEntry(zipEntry);
assertNull(jarEntry.getCertificates());
- // Regression Test for HARMONY-3424
+ // Regression Test for HARMONY-3424, b/1864326
String jarFileName = "TestCodeSigners.jar";
Support_Resources.copyFile(resources, null, jarFileName);
File file = new File(resources, jarFileName);
JarFile jarFile = new JarFile(file);
JarEntry jarEntry1 = jarFile.getJarEntry("Test.class");
JarEntry jarEntry2 = jarFile.getJarEntry("Test.class");
- InputStream in = jarFile.getInputStream(jarEntry1);
- byte[] buffer = new byte[1024];
- while (in.available() > 0) {
- assertNull("getCertificates() should be null until the entry is read",
- jarEntry1.getCertificates());
+
+ try (InputStream in = jarFile.getInputStream(jarEntry1)) {
+ // Code signers and certs must be {@code null} until the entry is completely
+ // read.
+ assertNull(jarEntry1.getCertificates());
assertNull(jarEntry2.getCertificates());
- in.read(buffer);
+ assertNull(jarEntry1.getCodeSigners());
+ assertNull(jarEntry2.getCodeSigners());
+
+ // Read a few bytes from the stream.
+ in.read(new byte[64]);
+ assertNull(jarEntry1.getCertificates());
+ assertNull(jarEntry2.getCertificates());
+ assertNull(jarEntry1.getCodeSigners());
+ assertNull(jarEntry2.getCodeSigners());
+
+ // Read the rest of the stream.
+ Streams.skipByReading(in, Long.MAX_VALUE);
+
+ assertEquals(-1, in.read());
+ assertNotNull(jarEntry1.getCodeSigners());
+ assertNotNull(jarEntry2.getCodeSigners());
+ assertNotNull(jarEntry1.getCertificates());
+ assertNotNull(jarEntry2.getCertificates());
}
- assertEquals("the file is fully read", -1, in.read());
- assertNotNull(jarEntry1.getCertificates());
- assertNotNull(jarEntry2.getCertificates());
- in.close();
}
- /**
- * java.util.jar.JarEntry#getCodeSigners()
- */
public void test_getCodeSigners() throws IOException {
String jarFileName = "TestCodeSigners.jar";
Support_Resources.copyFile(resources, null, jarFileName);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
index ec2f4f31..bb2265f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
@@ -17,7 +17,6 @@
package org.apache.harmony.tests.javax.net.ssl;
-import dalvik.annotation.AndroidOnly;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -334,7 +333,6 @@
* because our self-signed test certificates are not valid.)
*/
- @AndroidOnly("Uses bks key store. Change useBKS to false to run on the RI")
public void testClientAuth() throws Exception {
boolean useBKS = true;
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
index 11e3142..861f4a8 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/SSLSocketTest.java
@@ -15,7 +15,6 @@
*/
package org.apache.harmony.tests.javax.net.ssl;
-import dalvik.annotation.AndroidOnly;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -223,7 +222,7 @@
/**
* javax.net.ssl.SSLSocket#addHandshakeCompletedListener(HandshakeCompletedListener listener)
*/
- @AndroidOnly("RI doesn't throw the specified IAE")
+ // AndroidOnly("RI doesn't throw the specified IAE")
public void test_addHandshakeCompletedListener() throws IOException {
SSLSocket ssl = getSSLSocket();
HandshakeCompletedListener ls = new HandshakeCL();
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/OldSHA1PRNGSecureRandomTest.java
similarity index 87%
rename from luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java
rename to harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/OldSHA1PRNGSecureRandomTest.java
index 0db5ee1..b213b47 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/security/OldSHA1PRNGSecureRandomTest.java
@@ -15,10 +15,8 @@
* limitations under the License.
*/
-package org.apache.harmony.security.tests.provider.crypto;
+package org.apache.harmony.tests.javax.security;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
@@ -29,7 +27,7 @@
* Tests against methods in SecureRandom class object using
* SHA1PRNG_SecureRandomImpl.
*/
-public class SHA1PRNG_SecureRandomTest extends TestCase {
+public class OldSHA1PRNGSecureRandomTest extends TestCase {
private static final int LENGTH = 20; // constant defining loop limit
@@ -37,8 +35,6 @@
private static final String algorithm = "SHA1PRNG"; // algorithm's name
- private static final String provider = "Crypto"; // provider's name
-
private static SecureRandom sr; // fields used by tests
private static SecureRandom sr2; //
@@ -48,8 +44,8 @@
*/
protected void setUp() throws Exception {
super.setUp();
- sr = SecureRandom.getInstance(algorithm, provider);
- sr2 = SecureRandom.getInstance(algorithm, provider);
+ sr = SecureRandom.getInstance(algorithm);
+ sr2 = SecureRandom.getInstance(algorithm);
}
/**
@@ -189,8 +185,8 @@
byte[] myBytes2;
for (int i = 1; i < LENGTH / 2; i += INCR) {
- sr1 = SecureRandom.getInstance(algorithm, provider);
- sr2 = SecureRandom.getInstance(algorithm, provider);
+ sr1 = SecureRandom.getInstance(algorithm);
+ sr2 = SecureRandom.getInstance(algorithm);
boolean flag = true;
@@ -245,8 +241,8 @@
// case 1:
for (int i = 1; i < LENGTH / 2; i += INCR) {
- sr1 = SecureRandom.getInstance(algorithm, provider);
- sr2 = SecureRandom.getInstance(algorithm, provider);
+ sr1 = SecureRandom.getInstance(algorithm);
+ sr2 = SecureRandom.getInstance(algorithm);
sr1.nextBytes(new byte[0]);
sr2.nextBytes(new byte[0]);
@@ -286,8 +282,8 @@
byte[][] bytes1 = new byte[2][n];
byte[][] bytes2 = new byte[2][n];
- sr1 = SecureRandom.getInstance(algorithm, provider);
- sr2 = SecureRandom.getInstance(algorithm, provider);
+ sr1 = SecureRandom.getInstance(algorithm);
+ sr2 = SecureRandom.getInstance(algorithm);
sr1.setSeed(myBytes);
sr2.setSeed(myBytes);
@@ -402,31 +398,4 @@
assertFalse("sequences are equal i=" + i, b);
}
}
-
- public void testSeedIsFullLength() throws Exception {
- Class<?> srClass = Class.forName(
- "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
- Field seedField = srClass.getDeclaredField("seed");
- seedField.setAccessible(true);
-
- Method nextBytesMethod = srClass.getDeclaredMethod("engineNextBytes", byte[].class);
- nextBytesMethod.setAccessible(true);
-
- byte[] bytes = new byte[1];
-
- // Iterate 8 times to make sure the probability of a false positive is
- // extremely rare.
- for (int i = 0; i < 8; i++) {
- Object sr = srClass.newInstance();
- nextBytesMethod.invoke(sr, bytes);
- int[] seed = (int[]) seedField.get(sr);
-
- // If the first integer is not zero, it is fixed.
- if (seed[0] != 0) {
- return; // Success
- }
- }
-
- fail("Fallback SHA1PRNG_SecureRandomImpl should not clobber seed internally");
- }
}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserFactoryTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserFactoryTest.java
index 614b9d8..4e1ffdf 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserFactoryTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/xml/parsers/SAXParserFactoryTest.java
@@ -35,7 +35,6 @@
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.helpers.DefaultHandler;
-import dalvik.annotation.AndroidOnly;
import dalvik.annotation.KnownFailure;
public class SAXParserFactoryTest extends TestCase {
@@ -65,7 +64,7 @@
super.tearDown();
}
- @AndroidOnly("Android SAX implementation is non-validating")
+ // AndroidOnly("Android SAX implementation is non-validating")
public void test_Constructor() {
MySAXParserFactory mpf = new MySAXParserFactory();
assertTrue(mpf instanceof SAXParserFactory);
diff --git a/libart/src/main/java/java/lang/CaseMapper.java b/libart/src/main/java/java/lang/CaseMapper.java
index f23a4ef..5cf4ecf 100644
--- a/libart/src/main/java/java/lang/CaseMapper.java
+++ b/libart/src/main/java/java/lang/CaseMapper.java
@@ -18,7 +18,7 @@
import java.util.Locale;
import libcore.icu.ICU;
-import libcore.icu.Transliterator;
+import com.ibm.icu.text.Transliterator;
/**
* Performs case operations as described by http://unicode.org/reports/tr21/tr21-5.html.
@@ -138,7 +138,7 @@
private static final ThreadLocal<Transliterator> EL_UPPER = new ThreadLocal<Transliterator>() {
@Override protected Transliterator initialValue() {
- return new Transliterator("el-Upper");
+ return Transliterator.getInstance("el-Upper");
}
};
diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java
index bc54f89..0d37cd6 100644
--- a/libart/src/main/java/java/lang/Class.java
+++ b/libart/src/main/java/java/lang/Class.java
@@ -227,24 +227,12 @@
*/
private transient volatile int dexTypeIndex;
- /** Number of direct methods. */
- private transient int numDirectMethods;
-
- /** Number of instance fields. */
- private transient int numInstanceFields;
-
/** Number of instance fields that are object references. */
private transient int numReferenceInstanceFields;
/** Number of static fields that are object references. */
private transient int numReferenceStaticFields;
- /** Number of static fields. */
- private transient int numStaticFields;
-
- /** Number of virtual methods. */
- private transient int numVirtualMethods;
-
/**
* Total object size; used when allocating storage on GC heap. For interfaces and abstract
* classes this will be zero. See also {@link Class#classSize}.
@@ -583,7 +571,7 @@
* {@code (Class[]) null} is equivalent to the empty array.
* @return the method described by {@code name} and {@code parameterTypes}.
* @throws NoSuchMethodException
- * if the requested constructor cannot be found.
+ * if the requested method cannot be found.
* @throws NullPointerException
* if {@code name} is {@code null}.
* @see #getMethod(String, Class[])
@@ -1283,8 +1271,7 @@
Object[] iftable = c.ifTable;
if (iftable != null) {
for (int i = 0; i < iftable.length; i += 2) {
- Class<?> ifc = (Class<?>) iftable[i];
- if (ifc == this) {
+ if (iftable[i] == this) {
return true;
}
}
diff --git a/libart/src/main/java/java/lang/ClassLoader.java b/libart/src/main/java/java/lang/ClassLoader.java
index dfbeeb5..860e4a1 100644
--- a/libart/src/main/java/java/lang/ClassLoader.java
+++ b/libart/src/main/java/java/lang/ClassLoader.java
@@ -92,6 +92,11 @@
private Map<String, Package> packages = new HashMap<String, Package>();
/**
+ * Pointer to the class table, only used from within the runtime.
+ */
+ private transient long classTable;
+
+ /**
* To avoid unloading individual classes, {@link java.lang.reflect.Proxy}
* only generates one class for each set of interfaces. This maps sets of
* interfaces to the proxy class that implements all of them. It is declared
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index fcecf18..c43c1ba 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -43,6 +43,12 @@
public static FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException { return Libcore.os.accept(fd, peerAddress); }
/**
+ * TODO Change the public API by removing the overload above and unhiding this version.
+ * @hide
+ */
+ public static FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException { return Libcore.os.accept(fd, peerAddress); }
+
+ /**
* See <a href="http://man7.org/linux/man-pages/man2/access.2.html">access(2)</a>.
*/
public static boolean access(String path, int mode) throws ErrnoException { return Libcore.os.access(path, mode); }
@@ -215,6 +221,8 @@
*/
public static int getuid() { return Libcore.os.getuid(); }
+ /** @hide */ public static int getxattr(String path, String name, byte[] outValue) throws ErrnoException { return Libcore.os.getxattr(path, name, outValue); }
+
/**
* See <a href="http://man7.org/linux/man-pages/man3/if_indextoname.3.html">if_indextoname(3)</a>.
*/
@@ -389,6 +397,8 @@
*/
public static void remove(String path) throws ErrnoException { Libcore.os.remove(path); }
+ /** @hide */ public static void removexattr(String path, String name) throws ErrnoException { Libcore.os.removexattr(path, name); }
+
/**
* See <a href="http://man7.org/linux/man-pages/man2/rename.2.html">rename(2)</a>.
*/
@@ -468,6 +478,8 @@
*/
public static void setuid(int uid) throws ErrnoException { Libcore.os.setuid(uid); }
+ /** @hide */ public static void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException { Libcore.os.setxattr(path, name, value, flags); };
+
/**
* See <a href="http://man7.org/linux/man-pages/man2/shutdown.2.html">shutdown(2)</a>.
*/
@@ -534,6 +546,11 @@
public static StructUtsname uname() { return Libcore.os.uname(); }
/**
+ * @hide See <a href="http://man7.org/linux/man-pages/man2/unlink.2.html">unlink(2)</a>.
+ */
+ public static void unlink(String pathname) throws ErrnoException { Libcore.os.unlink(pathname); }
+
+ /**
* See <a href="http://man7.org/linux/man-pages/man3/unsetenv.3.html">unsetenv(3)</a>.
*/
public static void unsetenv(String name) throws ErrnoException { Libcore.os.unsetenv(name); }
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 6a99bb3..f0d77de 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -238,6 +238,7 @@
public static final int ETIME = placeholder();
public static final int ETIMEDOUT = placeholder();
public static final int ETXTBSY = placeholder();
+ /** @hide */ public static final int EUSERS = placeholder();
// On Linux, EWOULDBLOCK == EAGAIN. Use EAGAIN instead, to reduce confusion.
public static final int EXDEV = placeholder();
public static final int EXIT_FAILURE = placeholder();
@@ -349,6 +350,7 @@
public static final int O_RDONLY = placeholder();
public static final int O_RDWR = placeholder();
public static final int O_SYNC = placeholder();
+ /** @hide */ public static final int O_DSYNC = placeholder();
public static final int O_TRUNC = placeholder();
public static final int O_WRONLY = placeholder();
public static final int POLLERR = placeholder();
@@ -489,6 +491,8 @@
public static final int S_IXOTH = placeholder();
public static final int S_IXUSR = placeholder();
public static final int TCP_NODELAY = placeholder();
+ /** @hide */ public static final int TIOCOUTQ = placeholder();
+ /** @hide */ public static final int UNIX_PATH_MAX = placeholder();
public static final int WCONTINUED = placeholder();
public static final int WEXITED = placeholder();
public static final int WNOHANG = placeholder();
@@ -496,6 +500,8 @@
public static final int WSTOPPED = placeholder();
public static final int WUNTRACED = placeholder();
public static final int W_OK = placeholder();
+ /** @hide */ public static final int XATTR_CREATE = placeholder();
+ /** @hide */ public static final int XATTR_REPLACE = placeholder();
public static final int X_OK = placeholder();
public static final int _SC_2_CHAR_TERM = placeholder();
public static final int _SC_2_C_BIND = placeholder();
diff --git a/luni/src/main/java/android/system/UnixSocketAddress.java b/luni/src/main/java/android/system/UnixSocketAddress.java
new file mode 100644
index 0000000..e0ade78
--- /dev/null
+++ b/luni/src/main/java/android/system/UnixSocketAddress.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2015 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 java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+/**
+ * A UNIX-domain (AF_UNIX / AF_LOCAL) socket address.
+ *
+ * @hide
+ */
+public final class UnixSocketAddress extends SocketAddress {
+
+ private static final int NAMED_PATH_LENGTH = OsConstants.UNIX_PATH_MAX;
+ private static final byte[] UNNAMED_PATH = new byte[0];
+
+ // See unix(7): Three types of UnixSocketAddress:
+ // 1) pathname: 0 < sun_path.length <= NAMED_PATH_LENGTH, sun_path[0] != 0.
+ // 2) unnamed: sun_path = [].
+ // 3) abstract: 0 < sun_path.length <= NAMED_PATH_LENGTH, sun_path[0] == 0.
+ private byte[] sun_path;
+
+ /** This constructor is also used from JNI. */
+ private UnixSocketAddress(byte[] sun_path) {
+ if (sun_path == null) {
+ throw new IllegalArgumentException("sun_path must not be null");
+ }
+ if (sun_path.length > NAMED_PATH_LENGTH) {
+ throw new IllegalArgumentException("sun_path exceeds the maximum length");
+ }
+
+ if (sun_path.length == 0) {
+ this.sun_path = UNNAMED_PATH;
+ } else {
+ this.sun_path = new byte[sun_path.length];
+ System.arraycopy(sun_path, 0, this.sun_path, 0, sun_path.length);
+ }
+ }
+
+ /**
+ * Creates a named, abstract AF_UNIX socket address.
+ */
+ public static UnixSocketAddress createAbstract(String name) {
+ byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
+ // Abstract sockets have a path that starts with (byte) 0.
+ byte[] path = new byte[nameBytes.length + 1];
+ System.arraycopy(nameBytes, 0, path, 1, nameBytes.length);
+ return new UnixSocketAddress(path);
+ }
+
+ /**
+ * Creates a named, filesystem AF_UNIX socket address.
+ */
+ public static UnixSocketAddress createFileSystem(String pathName) {
+ byte[] pathNameBytes = pathName.getBytes(StandardCharsets.UTF_8);
+ // File system sockets have a path that ends with (byte) 0.
+ byte[] path = new byte[pathNameBytes.length + 1];
+ System.arraycopy(pathNameBytes, 0, path, 0, pathNameBytes.length);
+ return new UnixSocketAddress(path);
+ }
+
+ /**
+ * Creates an unnamed, filesystem AF_UNIX socket address.
+ */
+ public static UnixSocketAddress createUnnamed() {
+ return new UnixSocketAddress(UNNAMED_PATH);
+ }
+
+ /** Used for testing. */
+ public byte[] getSunPath() {
+ if (sun_path.length == 0) {
+ return sun_path;
+ }
+ byte[] sunPathCopy = new byte[sun_path.length];
+ System.arraycopy(sun_path, 0, sunPathCopy, 0, sun_path.length);
+ return sunPathCopy;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ UnixSocketAddress that = (UnixSocketAddress) o;
+ return Arrays.equals(sun_path, that.sun_path);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(sun_path);
+ }
+
+ @Override
+ public String toString() {
+ return "UnixSocketAddress[" +
+ "sun_path=" + Arrays.toString(sun_path) +
+ ']';
+ }
+}
diff --git a/luni/src/main/java/java/io/RandomAccessFile.java b/luni/src/main/java/java/io/RandomAccessFile.java
index 0e4fa4f..42c30c4 100644
--- a/luni/src/main/java/java/io/RandomAccessFile.java
+++ b/luni/src/main/java/java/io/RandomAccessFile.java
@@ -44,8 +44,6 @@
*/
private FileDescriptor fd;
- private boolean syncMetadata = false;
-
// The unique file channel associated with this FileInputStream (lazily
// initialized).
private FileChannel channel;
@@ -104,11 +102,11 @@
} else if (mode.equals("rw") || mode.equals("rws") || mode.equals("rwd")) {
flags = O_RDWR | O_CREAT;
if (mode.equals("rws")) {
- // Sync file and metadata with every write
- syncMetadata = true;
- } else if (mode.equals("rwd")) {
- // Sync file, but not necessarily metadata
+ // Sync data and metadata with every write
flags |= O_SYNC;
+ } else if (mode.equals("rwd")) {
+ // Sync data, but not necessarily metadata
+ flags |= O_DSYNC;
}
} else {
throw new IllegalArgumentException("Invalid mode: " + mode);
@@ -116,14 +114,6 @@
this.mode = flags;
this.fd = IoBridge.open(file.getPath(), flags);
- // if we are in "rws" mode, attempt to sync file+metadata
- if (syncMetadata) {
- try {
- fd.sync();
- } catch (IOException e) {
- // Ignored
- }
- }
guard.open("close");
}
@@ -635,10 +625,6 @@
seek(newLength);
}
- // if we are in "rws" mode, attempt to sync file+metadata
- if (syncMetadata) {
- fd.sync();
- }
}
/**
@@ -689,10 +675,6 @@
*/
public void write(byte[] buffer, int byteOffset, int byteCount) throws IOException {
IoBridge.write(fd, buffer, byteOffset, byteCount);
- // if we are in "rws" mode, attempt to sync file+metadata
- if (syncMetadata) {
- fd.sync();
- }
}
/**
diff --git a/luni/src/main/java/java/lang/reflect/Array.java b/luni/src/main/java/java/lang/reflect/Array.java
index a7dacfe..72e6717 100644
--- a/luni/src/main/java/java/lang/reflect/Array.java
+++ b/luni/src/main/java/java/lang/reflect/Array.java
@@ -371,7 +371,7 @@
} else if (componentType == void.class) {
throw new IllegalArgumentException("Can't allocate an array of void");
}
- throw new AssertionError();
+ throw new AssertionError(componentType.toString());
}
/*
diff --git a/luni/src/main/java/java/net/IDN.java b/luni/src/main/java/java/net/IDN.java
index 4e60209..dd256c2 100644
--- a/luni/src/main/java/java/net/IDN.java
+++ b/luni/src/main/java/java/net/IDN.java
@@ -16,7 +16,7 @@
package java.net;
-import libcore.icu.NativeIDN;
+import com.ibm.icu.text.IDNA;
/**
* Converts internationalized domain names between Unicode and the ASCII Compatible Encoding
@@ -61,7 +61,11 @@
* @throws IllegalArgumentException if {@code input} does not conform to <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>
*/
public static String toASCII(String input, int flags) {
- return NativeIDN.toASCII(input, flags);
+ try {
+ return IDNA.convertIDNToASCII(input, flags).toString();
+ } catch (com.ibm.icu.text.StringPrepParseException e) {
+ throw new IllegalArgumentException("Invalid input to toASCII: " + input, e);
+ }
}
/**
@@ -91,7 +95,28 @@
* or {@code ALLOW_UNASSIGNED | USE_STD3_ASCII_RULES}
*/
public static String toUnicode(String input, int flags) {
- return NativeIDN.toUnicode(input, flags);
+ try {
+ // ICU only translates separators to ASCII for toASCII.
+ // Java expects the translation for toUnicode too.
+ return convertFullStop(IDNA.convertIDNToUnicode(input, flags)).toString();
+ } catch (com.ibm.icu.text.StringPrepParseException e) {
+ // The RI documentation explicitly states that if the conversion was unsuccessful
+ // the original string is returned.
+ return input;
+ }
+ }
+
+ private static boolean isLabelSeperator(char c) {
+ return (c == '\u3002' || c == '\uff0e' || c == '\uff61');
+ }
+
+ private static StringBuffer convertFullStop(StringBuffer input) {
+ for (int i = 0; i < input.length(); i++) {
+ if (isLabelSeperator(input.charAt(i))) {
+ input.setCharAt(i, '.');
+ }
+ }
+ return input;
}
/**
@@ -101,6 +126,6 @@
* @return the Unicode name
*/
public static String toUnicode(String input) {
- return NativeIDN.toUnicode(input, 0);
+ return toUnicode(input, 0);
}
}
diff --git a/luni/src/main/java/java/net/InetUnixAddress.java b/luni/src/main/java/java/net/InetUnixAddress.java
deleted file mode 100644
index 51236e2..0000000
--- a/luni/src/main/java/java/net/InetUnixAddress.java
+++ /dev/null
@@ -1,48 +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 java.net;
-
-import java.nio.charset.StandardCharsets;
-
-import static android.system.OsConstants.*;
-
-/**
- * An AF_UNIX address. See {@link InetAddress}.
- * @hide
- */
-public final class InetUnixAddress extends InetAddress {
- /**
- * Constructs an AF_UNIX InetAddress for the given path.
- */
- public InetUnixAddress(String path) {
- this(path.getBytes(StandardCharsets.UTF_8));
- }
-
- /**
- * Constructs an AF_UNIX InetAddress for the given path.
- */
- public InetUnixAddress(byte[] path) {
- super(AF_UNIX, path, null);
- }
-
- /**
- * Returns a string form of this InetAddress.
- */
- @Override public String toString() {
- return "InetUnixAddress[" + new String(ipaddress, StandardCharsets.UTF_8) + "]";
- }
-}
diff --git a/luni/src/main/java/java/security/SecureRandom.java b/luni/src/main/java/java/security/SecureRandom.java
index 7a03801..8fbcc39 100644
--- a/luni/src/main/java/java/security/SecureRandom.java
+++ b/luni/src/main/java/java/security/SecureRandom.java
@@ -23,7 +23,6 @@
import libcore.io.SizeOf;
import org.apache.harmony.security.fortress.Engine;
import org.apache.harmony.security.fortress.Services;
-import org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl;
/**
* This class generates cryptographically secure pseudo-random numbers.
@@ -86,12 +85,8 @@
*/
public SecureRandom() {
super(0);
- Provider.Service service = Services.getSecureRandomService();
- if (service == null) {
- this.provider = null;
- this.secureRandomSpi = new SHA1PRNG_SecureRandomImpl();
- this.algorithm = "SHA1PRNG";
- } else {
+ final Provider.Service service = Services.getSecureRandomService();
+ if (service != null) {
try {
this.provider = service.getProvider();
this.secureRandomSpi = (SecureRandomSpi)service.newInstance(null);
@@ -99,6 +94,8 @@
} catch (Exception e) {
throw new RuntimeException(e);
}
+ } else {
+ throw new AssertionError("Services.getSecureRandomService() == null");
}
}
diff --git a/luni/src/main/java/java/security/Security.java b/luni/src/main/java/java/security/Security.java
index aeb189f..723b0eb 100644
--- a/luni/src/main/java/java/security/Security.java
+++ b/luni/src/main/java/java/security/Security.java
@@ -90,8 +90,7 @@
private static void registerDefaultProviders() {
secprops.put("security.provider.1", "com.android.org.conscrypt.OpenSSLProvider");
secprops.put("security.provider.2", "com.android.org.bouncycastle.jce.provider.BouncyCastleProvider");
- secprops.put("security.provider.3", "org.apache.harmony.security.provider.crypto.CryptoProvider");
- secprops.put("security.provider.4", "com.android.org.conscrypt.JSSEProvider");
+ secprops.put("security.provider.3", "com.android.org.conscrypt.JSSEProvider");
}
/**
diff --git a/luni/src/main/java/java/security/Signature.java b/luni/src/main/java/java/security/Signature.java
index b11abaa..7a21a46 100644
--- a/luni/src/main/java/java/security/Signature.java
+++ b/luni/src/main/java/java/security/Signature.java
@@ -687,16 +687,32 @@
}
@Override
+ protected int engineSign(byte[] outbuf, int offset, int len) throws SignatureException {
+ return getSpi().engineSign(outbuf, offset, len);
+ }
+
+ @Override
protected void engineUpdate(byte arg0) throws SignatureException {
getSpi().engineUpdate(arg0);
}
@Override
+ protected void engineUpdate(ByteBuffer input) {
+ getSpi().engineUpdate(input);
+ }
+
+ @Override
protected boolean engineVerify(byte[] arg0) throws SignatureException {
return getSpi().engineVerify(arg0);
}
@Override
+ protected boolean engineVerify(byte[] sigBytes, int offset, int length)
+ throws SignatureException {
+ return getSpi().engineVerify(sigBytes, offset, length);
+ }
+
+ @Override
protected void engineUpdate(byte[] arg0, int arg1, int arg2) throws SignatureException {
getSpi().engineUpdate(arg0, arg1, arg2);
}
@@ -707,6 +723,12 @@
}
@Override
+ protected void engineInitSign(PrivateKey arg0, SecureRandom arg1)
+ throws InvalidKeyException {
+ getSpi(arg0).engineInitSign(arg0, arg1);
+ }
+
+ @Override
protected void engineInitVerify(PublicKey arg0) throws InvalidKeyException {
getSpi(arg0).engineInitVerify(arg0);
}
@@ -717,6 +739,11 @@
}
@Override
+ protected AlgorithmParameters engineGetParameters() {
+ return getSpi().engineGetParameters();
+ }
+
+ @Override
protected void engineSetParameter(String arg0, Object arg1)
throws InvalidParameterException {
getSpi().engineSetParameter(arg0, arg1);
diff --git a/luni/src/main/java/java/security/security.properties b/luni/src/main/java/java/security/security.properties
index a06283b..289efa9 100644
--- a/luni/src/main/java/java/security/security.properties
+++ b/luni/src/main/java/java/security/security.properties
@@ -22,9 +22,8 @@
security.provider.1=com.android.org.conscrypt.OpenSSLProvider
# Android's stripped down BouncyCastle provider
security.provider.2=com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
-# Remaining Harmony providers
-security.provider.3=org.apache.harmony.security.provider.crypto.CryptoProvider
-security.provider.4=com.android.org.conscrypt.JSSEProvider
+# Android's provider of OpenSSL backed implementations
+security.provider.3=com.android.org.conscrypt.JSSEProvider
diff --git a/luni/src/main/java/java/text/Bidi.java b/luni/src/main/java/java/text/Bidi.java
index d73ea4a..65861a7 100644
--- a/luni/src/main/java/java/text/Bidi.java
+++ b/luni/src/main/java/java/text/Bidi.java
@@ -17,11 +17,6 @@
package java.text;
-import java.awt.font.NumericShaper;
-import java.awt.font.TextAttribute;
-import java.util.ArrayList;
-import java.util.Arrays;
-
/**
* Implements the <a href="http://unicode.org/reports/tr9/">Unicode Bidirectional Algorithm</a>.
*
@@ -58,33 +53,28 @@
*/
public static final int DIRECTION_RIGHT_TO_LEFT = 1;
- /**
- * TODO: if we care about performance, we might just want to use an int[] instead of a Run[].
- */
- static class Run {
- private final int start;
- private final int limit;
- private final int level;
-
- public Run(int start, int limit, int level) {
- this.start = start;
- this.limit = limit;
- this.level = level;
- }
-
- public int getLevel() {
- return level;
- }
-
- public int getLimit() {
- return limit;
- }
-
- public int getStart() {
- return start;
+ private static int translateConstToIcu(int javaInt) {
+ switch (javaInt) {
+ case DIRECTION_DEFAULT_LEFT_TO_RIGHT:
+ return com.ibm.icu.text.Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
+ case DIRECTION_DEFAULT_RIGHT_TO_LEFT:
+ return com.ibm.icu.text.Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
+ case DIRECTION_LEFT_TO_RIGHT:
+ return com.ibm.icu.text.Bidi.DIRECTION_LEFT_TO_RIGHT;
+ case DIRECTION_RIGHT_TO_LEFT:
+ return com.ibm.icu.text.Bidi.DIRECTION_RIGHT_TO_LEFT;
+ // If the parameter was unrecognized use LEFT_TO_RIGHT.
+ default:
+ return com.ibm.icu.text.Bidi.DIRECTION_LEFT_TO_RIGHT;
}
}
+ private boolean isUnidirectional() {
+ return icuBidi.getRunCount() == 0;
+ }
+
+ private final com.ibm.icu.text.Bidi icuBidi;
+
/**
* Creates a {@code Bidi} object from the {@code
* AttributedCharacterIterator} of a paragraph text. The RUN_DIRECTION
@@ -114,65 +104,7 @@
throw new IllegalArgumentException("paragraph is null");
}
- int begin = paragraph.getBeginIndex();
- int end = paragraph.getEndIndex();
- int length = end - begin;
- char[] text = new char[length + 1]; // One more char for AttributedCharacterIterator.DONE
-
- if (length != 0) {
- text[0] = paragraph.first();
- } else {
- paragraph.first();
- }
-
- // First check the RUN_DIRECTION attribute.
- int flags = DIRECTION_DEFAULT_LEFT_TO_RIGHT;
- Object direction = paragraph.getAttribute(TextAttribute.RUN_DIRECTION);
- if (direction != null && direction instanceof Boolean) {
- if (direction.equals(TextAttribute.RUN_DIRECTION_LTR)) {
- flags = DIRECTION_LEFT_TO_RIGHT;
- } else {
- flags = DIRECTION_RIGHT_TO_LEFT;
- }
- }
-
- // Retrieve the text and gather BIDI_EMBEDDINGS
- byte[] embeddings = null;
- for (int textLimit = 1, i = 1; i < length; textLimit = paragraph
- .getRunLimit(TextAttribute.BIDI_EMBEDDING)
- - begin + 1) {
- Object embedding = paragraph.getAttribute(TextAttribute.BIDI_EMBEDDING);
- if (embedding != null && embedding instanceof Integer) {
- int embLevel = ((Integer) embedding).intValue();
-
- if (embeddings == null) {
- embeddings = new byte[length];
- }
-
- for (; i < textLimit; i++) {
- text[i] = paragraph.next();
- embeddings[i - 1] = (byte) embLevel;
- }
- } else {
- for (; i < textLimit; i++) {
- text[i] = paragraph.next();
- }
- }
- }
-
- // Apply NumericShaper to the text
- Object numericShaper = paragraph.getAttribute(TextAttribute.NUMERIC_SHAPING);
- if (numericShaper != null && numericShaper instanceof NumericShaper) {
- ((NumericShaper) numericShaper).shape(text, 0, length);
- }
-
- long bidi = 0;
- try {
- bidi = createUBiDi(text, 0, embeddings, 0, length, flags);
- readBidiInfo(bidi);
- } finally {
- ubidi_close(bidi);
- }
+ this.icuBidi = new com.ibm.icu.text.Bidi(paragraph);
}
/**
@@ -214,13 +146,11 @@
if (text == null || text.length - textStart < paragraphLength) {
throw new IllegalArgumentException();
}
-
if (embeddings != null) {
if (embeddings.length - embStart < paragraphLength) {
throw new IllegalArgumentException();
}
}
-
if (textStart < 0) {
throw new IllegalArgumentException("Negative textStart value " + textStart);
}
@@ -231,13 +161,9 @@
throw new IllegalArgumentException("Negative paragraph length " + paragraphLength);
}
- long bidi = 0;
- try {
- bidi = createUBiDi(text, textStart, embeddings, embStart, paragraphLength, flags);
- readBidiInfo(bidi);
- } finally {
- ubidi_close(bidi);
- }
+ this.icuBidi = new com.ibm.icu.text.Bidi(text, textStart, embeddings, embStart,
+ paragraphLength, translateConstToIcu(flags));
+
}
/**
@@ -261,109 +187,18 @@
(paragraph == null ? 0 : paragraph.length()), flags);
}
- // create the native UBiDi struct, need to be closed with ubidi_close().
- private static long createUBiDi(char[] text, int textStart,
- byte[] embeddings, int embStart, int paragraphLength, int flags) {
- char[] realText = null;
- byte[] realEmbeddings = null;
-
- if (text == null || text.length - textStart < paragraphLength) {
- throw new IllegalArgumentException();
- }
- realText = new char[paragraphLength];
- System.arraycopy(text, textStart, realText, 0, paragraphLength);
-
- if (embeddings != null) {
- if (embeddings.length - embStart < paragraphLength) {
- throw new IllegalArgumentException();
- }
- if (paragraphLength > 0) {
- Bidi temp = new Bidi(text, textStart, null, 0, paragraphLength, flags);
- realEmbeddings = new byte[paragraphLength];
- System.arraycopy(temp.offsetLevel, 0, realEmbeddings, 0, paragraphLength);
- for (int i = 0; i < paragraphLength; i++) {
- byte e = embeddings[i];
- if (e < 0) {
- realEmbeddings[i] = (byte) (UBIDI_LEVEL_OVERRIDE - e);
- } else if (e > 0) {
- realEmbeddings[i] = e;
- } else {
- realEmbeddings[i] |= (byte) UBIDI_LEVEL_OVERRIDE;
- }
- }
- }
- }
-
- if (flags > 1 || flags < -2) {
- flags = 0;
- }
-
- long bidi = 0;
- boolean needsDeletion = true;
- try {
- bidi = ubidi_open();
- ubidi_setPara(bidi, realText, paragraphLength, flags, realEmbeddings);
- needsDeletion = false;
- } finally {
- if (needsDeletion) {
- ubidi_close(bidi);
- }
- }
- return bidi;
+ private Bidi(com.ibm.icu.text.Bidi icuBidi) {
+ this.icuBidi = icuBidi;
}
- /* private constructor used by createLineBidi() */
- private Bidi(long pBidi) {
- readBidiInfo(pBidi);
- }
-
- // read info from the native UBiDi struct
- private void readBidiInfo(long pBidi) {
- length = ubidi_getLength(pBidi);
-
- offsetLevel = (length == 0) ? null : ubidi_getLevels(pBidi);
-
- baseLevel = ubidi_getParaLevel(pBidi);
-
- int runCount = ubidi_countRuns(pBidi);
- if (runCount == 0) {
- unidirectional = true;
- runs = null;
- } else if (runCount < 0) {
- runs = null;
- } else {
- runs = ubidi_getRuns(pBidi);
-
- // Simplified case for one run which has the base level
- if (runCount == 1 && runs[0].getLevel() == baseLevel) {
- unidirectional = true;
- runs = null;
- }
- }
-
- direction = ubidi_getDirection(pBidi);
- }
-
- private int baseLevel;
-
- private int length;
-
- private byte[] offsetLevel;
-
- private Run[] runs;
-
- private int direction;
-
- private boolean unidirectional;
-
/**
* Returns whether the base level is from left to right.
*
* @return true if the base level is from left to right.
*/
public boolean baseIsLeftToRight() {
- return baseLevel % 2 == 0 ? true : false;
+ return icuBidi.baseIsLeftToRight();
}
/**
@@ -382,55 +217,36 @@
* than the length of this object's paragraph text.
*/
public Bidi createLineBidi(int lineStart, int lineLimit) {
- if (lineStart < 0 || lineLimit < 0 || lineLimit > length || lineStart > lineLimit) {
+ if (lineStart < 0 || lineLimit < 0 || lineLimit > getLength() || lineStart > lineLimit) {
throw new IllegalArgumentException("Invalid ranges (start=" + lineStart + ", " +
- "limit=" + lineLimit + ", length=" + length + ")");
+ "limit=" + lineLimit + ", length=" + getLength() + ")");
}
- char[] text = new char[this.length];
- Arrays.fill(text, 'a');
- byte[] embeddings = new byte[this.length];
- for (int i = 0; i < embeddings.length; i++) {
- embeddings[i] = (byte) -this.offsetLevel[i];
+ // In the special case where the start and end positions are the same, we return a new bidi
+ // instance which is empty. Note that the default constructor for an empty ICU4J bidi
+ // instance is not the same as passing in empty values. This way allows one to call
+ // .getLength() for example and return a correct value instead of an IllegalStateException
+ // being thrown, which happens in the case of using the empty constructor.
+ if (lineStart == lineLimit) {
+ return new Bidi(new com.ibm.icu.text.Bidi(new char[] {}, 0, new byte[] {}, 0, 0,
+ translateConstToIcu(DIRECTION_LEFT_TO_RIGHT)));
}
- int dir = this.baseIsLeftToRight()
- ? Bidi.DIRECTION_LEFT_TO_RIGHT
- : Bidi.DIRECTION_RIGHT_TO_LEFT;
- long parent = 0;
- try {
- parent = createUBiDi(text, 0, embeddings, 0, this.length, dir);
- if (lineStart == lineLimit) {
- return createEmptyLineBidi(parent);
- }
- return new Bidi(ubidi_setLine(parent, lineStart, lineLimit));
- } finally {
- ubidi_close(parent);
- }
- }
-
- private Bidi createEmptyLineBidi(long parent) {
- // ICU4C doesn't allow this case, but the RI does.
- Bidi result = new Bidi(parent);
- result.length = 0;
- result.offsetLevel = null;
- result.runs = null;
- result.unidirectional = true;
- return result;
+ return new Bidi(icuBidi.createLineBidi(lineStart, lineLimit));
}
/**
* Returns the base level.
*/
public int getBaseLevel() {
- return baseLevel;
+ return icuBidi.getBaseLevel();
}
/**
* Returns the length of the text.
*/
public int getLength() {
- return length;
+ return icuBidi.getLength();
}
/**
@@ -438,9 +254,9 @@
*/
public int getLevelAt(int offset) {
try {
- return offsetLevel[offset] & ~UBIDI_LEVEL_OVERRIDE;
- } catch (RuntimeException e) {
- return baseLevel;
+ return icuBidi.getLevelAt(offset);
+ } catch (IllegalArgumentException e) {
+ return getBaseLevel();
}
}
@@ -448,28 +264,43 @@
* Returns the number of runs in the text, at least 1.
*/
public int getRunCount() {
- return unidirectional ? 1 : runs.length;
+ return isUnidirectional() ? 1 : icuBidi.getRunCount();
}
/**
* Returns the level of the given run.
*/
public int getRunLevel(int run) {
- return unidirectional ? baseLevel : runs[run].getLevel();
+ // Paper over a the ICU4J behaviour of strictly enforcing run must be strictly less than
+ // the number of runs. Done to maintain compatibility with previous C implementation.
+ if (run == getRunCount()) {
+ return getBaseLevel();
+ }
+ return isUnidirectional() ? icuBidi.getBaseLevel() : icuBidi.getRunLevel(run);
}
/**
* Returns the limit offset of the given run.
*/
public int getRunLimit(int run) {
- return unidirectional ? length : runs[run].getLimit();
+ // Paper over a the ICU4J behaviour of strictly enforcing run must be strictly less than
+ // the number of runs. Done to maintain compatibility with previous C implementation.
+ if (run == getRunCount()) {
+ return getBaseLevel();
+ }
+ return isUnidirectional() ? icuBidi.getLength() : icuBidi.getRunLimit(run);
}
/**
* Returns the start offset of the given run.
*/
public int getRunStart(int run) {
- return unidirectional ? 0 : runs[run].getStart();
+ // Paper over a the ICU4J behaviour of strictly enforcing run must be strictly less than
+ // the number of runs. Done to maintain compatibility with previous C implementation.
+ if (run == getRunCount()) {
+ return getBaseLevel();
+ }
+ return isUnidirectional() ? 0 : icuBidi.getRunStart(run);
}
/**
@@ -477,14 +308,14 @@
* direction and the text direction is from left to right.
*/
public boolean isLeftToRight() {
- return direction == UBiDiDirection_UBIDI_LTR;
+ return icuBidi.isLeftToRight();
}
/**
* Returns true if the text direction is mixed.
*/
public boolean isMixed() {
- return direction == UBiDiDirection_UBIDI_MIXED;
+ return icuBidi.isMixed();
}
/**
@@ -492,7 +323,7 @@
* direction and the text direction is from right to left.
*/
public boolean isRightToLeft() {
- return direction == UBiDiDirection_UBIDI_RTL;
+ return icuBidi.isRightToLeft();
}
/**
@@ -519,6 +350,7 @@
*/
public static void reorderVisually(byte[] levels, int levelStart,
Object[] objects, int objectStart, int count) {
+
if (count < 0 || levelStart < 0 || objectStart < 0
|| count > levels.length - levelStart
|| count > objects.length - objectStart) {
@@ -527,17 +359,7 @@
", objectStart=" + objectStart + ", count=" + count + ")");
}
- byte[] realLevels = new byte[count];
- System.arraycopy(levels, levelStart, realLevels, 0, count);
-
- int[] indices = ubidi_reorderVisual(realLevels, count);
-
- ArrayList<Object> result = new ArrayList<Object>(count);
- for (int i = 0; i < count; i++) {
- result.add(objects[objectStart + indices[i]]);
- }
-
- System.arraycopy(result.toArray(), 0, objects, objectStart, count);
+ com.ibm.icu.text.Bidi.reorderVisually(levels, levelStart, objects, objectStart, count);
}
/**
@@ -562,33 +384,13 @@
throw new IllegalArgumentException();
}
- Bidi bidi = new Bidi(text, start, null, 0, limit - start, 0);
- return !bidi.isLeftToRight();
+ return com.ibm.icu.text.Bidi.requiresBidi(text, start, limit);
}
@Override
public String toString() {
return getClass().getName()
- + "[direction: " + direction + " baseLevel: " + baseLevel
- + " length: " + length + " runs: " + Arrays.toString(runs) + "]";
+ + "[direction: " + icuBidi.getDirection() + " baseLevel: " + icuBidi.getBaseLevel()
+ + " length: " + icuBidi.getLength() + " runs: " + icuBidi.getRunCount() + "]";
}
-
- // ICU4C constants.
- private static final int UBIDI_LEVEL_OVERRIDE = 0x80;
- private static final int UBiDiDirection_UBIDI_LTR = 0;
- private static final int UBiDiDirection_UBIDI_RTL = 1;
- private static final int UBiDiDirection_UBIDI_MIXED = 2;
-
- // ICU4C functions.
- private static native long ubidi_open();
- private static native void ubidi_close(long pBiDi);
- private static native void ubidi_setPara(long pBiDi, char[] text, int length, int paraLevel, byte[] embeddingLevels);
- private static native long ubidi_setLine(final long pParaBiDi, int start, int limit);
- private static native int ubidi_getDirection(final long pBiDi);
- private static native int ubidi_getLength(final long pBiDi);
- private static native byte ubidi_getParaLevel(final long pBiDi);
- private static native byte[] ubidi_getLevels(long pBiDi);
- private static native int ubidi_countRuns(long pBiDi);
- private static native Bidi.Run[] ubidi_getRuns(long pBidi);
- private static native int[] ubidi_reorderVisual(byte[] levels, int length);
}
diff --git a/luni/src/main/java/java/text/Normalizer.java b/luni/src/main/java/java/text/Normalizer.java
index 2e6647e..5355014 100644
--- a/luni/src/main/java/java/text/Normalizer.java
+++ b/luni/src/main/java/java/text/Normalizer.java
@@ -16,8 +16,6 @@
package java.text;
-import libcore.icu.NativeNormalizer;
-
/**
* Provides normalization functions according to
* <a href="http://www.unicode.org/unicode/reports/tr15/tr15-23.html">Unicode Standard Annex #15:
@@ -36,22 +34,32 @@
/**
* Normalization Form D - Canonical Decomposition.
*/
- NFD,
+ NFD(com.ibm.icu.text.Normalizer.NFD),
/**
* Normalization Form C - Canonical Decomposition, followed by Canonical Composition.
*/
- NFC,
+ NFC(com.ibm.icu.text.Normalizer.NFC),
/**
* Normalization Form KD - Compatibility Decomposition.
*/
- NFKD,
+ NFKD(com.ibm.icu.text.Normalizer.NFKD),
/**
* Normalization Form KC - Compatibility Decomposition, followed by Canonical Composition.
*/
- NFKC;
+ NFKC(com.ibm.icu.text.Normalizer.NFKC);
+
+ private final com.ibm.icu.text.Normalizer.Mode icuForm;
+
+ Form(com.ibm.icu.text.Normalizer.Mode icuForm) {
+ this.icuForm = icuForm;
+ }
+
+ com.ibm.icu.text.Normalizer.Mode getIcuForm() {
+ return icuForm;
+ }
}
/**
@@ -63,7 +71,7 @@
* @return true if normalized according to <code>form</code>
*/
public static boolean isNormalized(CharSequence src, Form form) {
- return NativeNormalizer.isNormalized(src, form);
+ return com.ibm.icu.text.Normalizer.isNormalized(src.toString(), form.getIcuForm(), 0);
}
/**
@@ -75,7 +83,7 @@
* @return string normalized according to <code>form</code>
*/
public static String normalize(CharSequence src, Form form) {
- return NativeNormalizer.normalize(src, form);
+ return com.ibm.icu.text.Normalizer.normalize(src.toString(), form.getIcuForm());
}
private Normalizer() {}
diff --git a/luni/src/main/java/java/util/zip/InflaterInputStream.java b/luni/src/main/java/java/util/zip/InflaterInputStream.java
index e5ad3db..a558f34 100644
--- a/luni/src/main/java/java/util/zip/InflaterInputStream.java
+++ b/luni/src/main/java/java/util/zip/InflaterInputStream.java
@@ -193,6 +193,8 @@
} else {
if ((len = in.read(buf)) > 0) {
inf.setInput(buf, 0, len);
+ } else if (len == -1) {
+ throw new EOFException("Unexpected end of stream.");
}
}
}
diff --git a/luni/src/main/java/java/util/zip/Zip64.java b/luni/src/main/java/java/util/zip/Zip64.java
index 9be3d1c..3060670 100644
--- a/luni/src/main/java/java/util/zip/Zip64.java
+++ b/luni/src/main/java/java/util/zip/Zip64.java
@@ -19,6 +19,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
+import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -37,8 +38,10 @@
/**
* The maximum supported entry / archive size for standard (non zip64) entries and archives.
+ *
+ * @hide
*/
- static final long MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE = 0x00000000ffffffffL;
+ public static final long MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE = 0x00000000ffffffffL;
/**
* The header ID of the zip64 extended info header. This value is used to identify
@@ -46,11 +49,6 @@
*/
private static final short ZIP64_EXTENDED_INFO_HEADER_ID = 0x0001;
- /**
- * The minimum size of the zip64 extended info header. This excludes the 2 byte header ID
- * and the 2 byte size.
- */
- private static final int ZIP64_EXTENDED_INFO_MIN_SIZE = 28;
/*
* Size (in bytes) of the zip64 end of central directory locator. This will be located
@@ -191,35 +189,32 @@
if (extendedInfoSize != -1) {
extendedInfoStart = buf.position();
try {
- if (extendedInfoSize < ZIP64_EXTENDED_INFO_MIN_SIZE) {
- throw new ZipException("Invalid zip64 extended info size: " + extendedInfoSize);
- }
-
// The size & compressed size only make sense in the central directory *or* if
// we know them beforehand. If we don't know them beforehand, they're stored in
// the data descriptor and should be read from there.
+ //
+ // Note that the spec says that the local file header "MUST" contain the
+ // original and compressed size fields. We don't care too much about that.
+ // The spec claims that the order of fields is fixed anyway.
if (fromCentralDirectory || (ze.getMethod() == ZipEntry.STORED)) {
- final long zip64Size = buf.getLong();
if (ze.size == MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE) {
- ze.size = zip64Size;
+ ze.size = buf.getLong();
}
- final long zip64CompressedSize = buf.getLong();
if (ze.compressedSize == MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE) {
- ze.compressedSize = zip64CompressedSize;
+ ze.compressedSize = buf.getLong();
}
}
// The local header offset is significant only in the central directory. It makes no
// sense within the local header itself.
if (fromCentralDirectory) {
- final long zip64LocalHeaderRelOffset = buf.getLong();
if (ze.localHeaderRelOffset == MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE) {
- ze.localHeaderRelOffset = zip64LocalHeaderRelOffset;
+ ze.localHeaderRelOffset = buf.getLong();
}
}
} catch (BufferUnderflowException bue) {
- ZipException zipException = new ZipException("Error parsing extendend info ");
+ ZipException zipException = new ZipException("Error parsing extended info");
zipException.initCause(bue);
throw zipException;
}
@@ -273,8 +268,20 @@
*/
public static void insertZip64ExtendedInfoToExtras(ZipEntry ze) throws ZipException {
final byte[] output;
- // We add 4 to ZIP64_EXTENDED_INFO_MIN_SIZE to account for the 2 byte header and length.
- final int extendedInfoSize = ZIP64_EXTENDED_INFO_MIN_SIZE + 4;
+ // We always write the size, uncompressed size and local rel header offset in all our
+ // Zip64 extended info headers (in both the local file header as well as the central
+ // directory). We always omit the disk number because we don't support spanned
+ // archives anyway.
+ //
+ // 2 bytes : Zip64 Extended Info Header ID
+ // 2 bytes : Zip64 Extended Info Field Size.
+ // 8 bytes : Uncompressed size
+ // 8 bytes : Compressed size
+ // 8 bytes : Local header rel offset.
+ // ----------
+ // 28 bytes : total
+ final int extendedInfoSize = 28;
+
if (ze.extra == null) {
output = new byte[extendedInfoSize];
} else {
@@ -291,13 +298,15 @@
// This means that people that for ZipOutputStream users, the value ZipEntry.getExtra
// after an entry is written will be different from before. This shouldn't be an issue
// in practice.
- output = new byte[ze.extra.length + ZIP64_EXTENDED_INFO_MIN_SIZE + 4];
- System.arraycopy(ze.extra, 0, output, ZIP64_EXTENDED_INFO_MIN_SIZE + 4, ze.extra.length);
+ output = new byte[ze.extra.length + extendedInfoSize];
+ System.arraycopy(ze.extra, 0, output, extendedInfoSize, ze.extra.length);
}
ByteBuffer bb = ByteBuffer.wrap(output).order(ByteOrder.LITTLE_ENDIAN);
bb.putShort(ZIP64_EXTENDED_INFO_HEADER_ID);
- bb.putShort((short) ZIP64_EXTENDED_INFO_MIN_SIZE);
+ // We subtract four because extendedInfoSize includes the ID and field
+ // size itself.
+ bb.putShort((short) (extendedInfoSize - 4));
if (ze.getMethod() == ZipEntry.STORED) {
bb.putLong(ze.size);
@@ -311,7 +320,6 @@
// The offset is only relevant in the central directory entry, but we write it out here
// anyway, since we know what it is.
bb.putLong(ze.localHeaderRelOffset);
- bb.putInt(0); // disk number
ze.extra = output;
}
@@ -354,23 +362,29 @@
* we could calculate the correct sizes only after writing out the entry. In this case,
* the local file header would not contain real sizes, and they would be present in the
* data descriptor and the central directory only.
+ *
+ * We choose the simplest strategy of always writing out the size, compressedSize and
+ * local header offset in all our Zip64 Extended info records.
*/
public static void refreshZip64ExtendedInfo(ZipEntry ze) {
- if (ze.extra == null || ze.extra.length < ZIP64_EXTENDED_INFO_MIN_SIZE) {
+ if (ze.extra == null) {
throw new IllegalStateException("Zip64 entry has no available extras: " + ze);
}
-
ByteBuffer buf = ByteBuffer.wrap(ze.extra).order(ByteOrder.LITTLE_ENDIAN);
- if (getZip64ExtendedInfoSize(buf) == -1) {
+ final int extendedInfoSize = getZip64ExtendedInfoSize(buf);
+ if (extendedInfoSize == -1) {
throw new IllegalStateException(
"Zip64 entry extras has no zip64 extended info record: " + ze);
}
- buf.putLong(ze.size);
- buf.putLong(ze.compressedSize);
- buf.putLong(ze.localHeaderRelOffset);
- buf.putInt(0); // disk number.
+ try {
+ buf.putLong(ze.size);
+ buf.putLong(ze.compressedSize);
+ buf.putLong(ze.localHeaderRelOffset);
+ } catch (BufferOverflowException boe) {
+ throw new IllegalStateException("Invalid extended info extra", boe);
+ }
}
public static void writeZip64EocdRecordAndLocator(ByteArrayOutputStream baos,
diff --git a/luni/src/main/java/java/util/zip/ZipEntry.java b/luni/src/main/java/java/util/zip/ZipEntry.java
index 26f6863..a06f1b6 100644
--- a/luni/src/main/java/java/util/zip/ZipEntry.java
+++ b/luni/src/main/java/java/util/zip/ZipEntry.java
@@ -66,7 +66,8 @@
*/
public static final int STORED = 0;
- ZipEntry(String name, String comment, long crc, long compressedSize,
+ /** @hide - for testing only */
+ public ZipEntry(String name, String comment, long crc, long compressedSize,
long size, int compressionMethod, int time, int modDate, byte[] extra,
long localHeaderRelOffset, long dataOffset) {
this.name = name;
diff --git a/luni/src/main/java/java/util/zip/ZipInputStream.java b/luni/src/main/java/java/util/zip/ZipInputStream.java
index f3ca74e..f254ba2 100644
--- a/luni/src/main/java/java/util/zip/ZipInputStream.java
+++ b/luni/src/main/java/java/util/zip/ZipInputStream.java
@@ -112,7 +112,11 @@
@Override
public void close() throws IOException {
if (!closed) {
- closeEntry(); // Close the current entry
+ try {
+ closeEntry(); // Close the current entry
+ } catch (IOException ignored) {
+ }
+
super.close();
}
}
diff --git a/luni/src/main/java/java/util/zip/ZipOutputStream.java b/luni/src/main/java/java/util/zip/ZipOutputStream.java
index 7748cfd..dfd85b6 100644
--- a/luni/src/main/java/java/util/zip/ZipOutputStream.java
+++ b/luni/src/main/java/java/util/zip/ZipOutputStream.java
@@ -260,7 +260,11 @@
writeIntAsUint16(cDir, 0); // Disk Start
writeIntAsUint16(cDir, 0); // Internal File Attributes
writeLongAsUint32(cDir, 0); // External File Attributes
- writeLongAsUint32(cDir, offset);
+ if (currentEntryNeedsZip64) {
+ writeLongAsUint32(cDir, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE);
+ } else {
+ writeLongAsUint32(cDir, currentEntry.localHeaderRelOffset);
+ }
cDir.write(nameBytes);
nameBytes = null;
if (currentEntry.extra != null) {
diff --git a/luni/src/main/java/javax/crypto/Cipher.java b/luni/src/main/java/javax/crypto/Cipher.java
index 9d6bd22..b27ea88 100644
--- a/luni/src/main/java/javax/crypto/Cipher.java
+++ b/luni/src/main/java/javax/crypto/Cipher.java
@@ -108,6 +108,50 @@
};
/**
+ * Used to keep track of which underlying {@code CipherSpi#engineInit(...)}
+ * variant to call when testing suitability.
+ */
+ private static enum InitType {
+ KEY, ALGORITHM_PARAMS, ALGORITHM_PARAM_SPEC,
+ };
+
+ /**
+ * Keeps track of the possible arguments to {@code Cipher#init(...)}.
+ */
+ private static class InitParams {
+ private final InitType initType;
+ private final int opmode;
+ private final Key key;
+ private final SecureRandom random;
+ private final AlgorithmParameterSpec spec;
+ private final AlgorithmParameters params;
+
+ private InitParams(InitType initType, int opmode, Key key, SecureRandom random,
+ AlgorithmParameterSpec spec, AlgorithmParameters params) {
+ this.initType = initType;
+ this.opmode = opmode;
+ this.key = key;
+ this.random = random;
+ this.spec = spec;
+ this.params = params;
+ }
+ }
+
+ /**
+ * Expresses the various types of transforms that may be used during
+ * initialization.
+ */
+ private static class Transform {
+ private final String name;
+ private final NeedToSet needToSet;
+
+ public Transform(String name, NeedToSet needToSet) {
+ this.name = name;
+ this.needToSet = needToSet;
+ }
+ }
+
+ /**
* The service name.
*/
private static final String SERVICE = "Cipher";
@@ -298,14 +342,15 @@
String[] transformParts = checkTransformation(transformation);
- boolean providerSupportsAlgorithm;
+ Engine.SpiAndProvider sap;
try {
- providerSupportsAlgorithm =
- tryCombinations(null /* key */, provider, transformParts) != null;
- } catch (InvalidKeyException e) {
- throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+ sap = tryCombinations(null /* params */, provider, transformation, transformParts);
+ } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+ // should never happen since we passed in null params
+ throw new ProviderException(e);
}
- if (!providerSupportsAlgorithm) {
+
+ if (sap == null) {
if (provider == null) {
throw new NoSuchAlgorithmException("No provider found for " + transformation);
} else {
@@ -316,6 +361,25 @@
return new Cipher(transformation, transformParts, provider);
}
+ /**
+ * Checks that the provided algorithm {@code transformation} string is a
+ * valid input. The algorithm is the only mandatory field and input can be
+ * of the form:
+ * <ul>
+ * <li><code>"[cipher]"</code>
+ * <li><code>"[cipher]/[mode]/[padding]"</code>
+ * <li><code>"[cipher]//[padding]"</code>
+ * <li><code>"[cipher]/[mode]"</code>
+ * </ul>
+ * <p>
+ * Returns the specified transformation split up into three parts
+ * corresponding to their function:
+ * <p>
+ * <code>
+ * {<algorithm>, <mode>, <padding>}
+ * </code>
+ * <p>
+ */
private static String[] checkTransformation(String transformation)
throws NoSuchAlgorithmException {
// ignore an extra prefix / characters such as in
@@ -347,25 +411,33 @@
}
/**
- * Makes sure a CipherSpi that matches this type is selected.
+ * Makes sure a CipherSpi that matches this type is selected. If
+ * {@code key != null} then it assumes that a suitable provider exists for
+ * this instance (used by {@link #init}. If the {@code initParams} is passed
+ * in, then the {@code CipherSpi} returned will be initialized.
*
* @throws InvalidKeyException if the specified key cannot be used to
* initialize this cipher.
+ * @throws InvalidAlgorithmParameterException
*/
- private CipherSpi getSpi(Key key) throws InvalidKeyException {
+ private CipherSpi getSpi(InitParams initParams) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
if (specifiedSpi != null) {
return specifiedSpi;
}
synchronized (initLock) {
- if (spiImpl != null && key == null) {
+ // This is not only a matter of performance. Many methods like update, doFinal, etc.
+ // call {@code #getSpi()} (ie, {@code #getSpi(null /* params */)}) and without this
+ // shortcut they would override an spi that was chosen using the key.
+ if (spiImpl != null && initParams == null) {
return spiImpl;
}
- final Engine.SpiAndProvider sap = tryCombinations(
- key, specifiedProvider, transformParts);
+ final Engine.SpiAndProvider sap = tryCombinations(initParams, specifiedProvider,
+ transformation, transformParts);
if (sap == null) {
- throw new ProviderException("No provider for " + transformation);
+ throw new ProviderException("No provider found for " + transformation);
}
spiImpl = (CipherSpi) sap.spi;
@@ -381,8 +453,8 @@
private CipherSpi getSpi() {
try {
return getSpi(null);
- } catch (InvalidKeyException e) {
- throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+ } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+ throw new ProviderException("Exception thrown when params == null", e);
}
}
@@ -403,84 +475,105 @@
}
/**
- * Try all combinations of mode strings:
- *
- * <pre>
- * [cipher]/[mode]/[padding]
- * [cipher]/[mode]
- * [cipher]//[padding]
- * [cipher]
- * </pre>
- *
- * @throws InvalidKeyException if the specified key cannot be used to
- * initialize any provider.
+ * Tries to find the correct {@code Cipher} transform to use. Returns a
+ * {@link Engine.SpiAndProvider}, throws the first exception that was
+ * encountered during attempted initialization, or {@code null} if there are
+ * no providers that support the {@code initParams}.
+ * <p>
+ * {@code transformParts} must be in the format returned by
+ * {@link #checkTransformation(String)}. The combinations of mode strings
+ * tried are as follows:
+ * <ul>
+ * <li><code>[cipher]/[mode]/[padding]</code>
+ * <li><code>[cipher]/[mode]</code>
+ * <li><code>[cipher]//[padding]</code>
+ * <li><code>[cipher]</code>
+ * </ul>
*/
- private static Engine.SpiAndProvider tryCombinations(Key key, Provider provider,
- String[] transformParts) throws InvalidKeyException {
- Engine.SpiAndProvider sap = null;
-
+ private static Engine.SpiAndProvider tryCombinations(InitParams initParams, Provider provider,
+ String transformation, String[] transformParts) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ // Enumerate all the transforms we need to try
+ ArrayList<Transform> transforms = new ArrayList<Transform>();
if (transformParts[1] != null && transformParts[2] != null) {
- sap = tryTransform(key, provider, transformParts[0] + "/" + transformParts[1] + "/"
- + transformParts[2], transformParts, NeedToSet.NONE);
- if (sap != null) {
- return sap;
- }
+ transforms.add(new Transform(transformParts[0] + "/" + transformParts[1] + "/"
+ + transformParts[2], NeedToSet.NONE));
}
-
if (transformParts[1] != null) {
- sap = tryTransform(key, provider, transformParts[0] + "/" + transformParts[1],
- transformParts, NeedToSet.PADDING);
- if (sap != null) {
- return sap;
- }
+ transforms.add(new Transform(transformParts[0] + "/" + transformParts[1],
+ NeedToSet.PADDING));
}
-
if (transformParts[2] != null) {
- sap = tryTransform(key, provider, transformParts[0] + "//" + transformParts[2],
- transformParts, NeedToSet.MODE);
- if (sap != null) {
- return sap;
- }
+ transforms.add(new Transform(transformParts[0] + "//" + transformParts[2],
+ NeedToSet.MODE));
}
+ transforms.add(new Transform(transformParts[0], NeedToSet.BOTH));
- return tryTransform(key, provider, transformParts[0], transformParts, NeedToSet.BOTH);
- }
-
- /**
- * @throws InvalidKeyException if the specified key cannot be used to
- * initialize this cipher.
- */
- private static Engine.SpiAndProvider tryTransform(Key key, Provider provider, String transform,
- String[] transformParts, NeedToSet type) throws InvalidKeyException {
- if (provider != null) {
- Provider.Service service = provider.getService(SERVICE, transform);
- if (service == null) {
- return null;
+ // Try each of the transforms and keep track of the first exception
+ // encountered.
+ Exception cause = null;
+ for (Transform transform : transforms) {
+ if (provider != null) {
+ Provider.Service service = provider.getService(SERVICE, transform.name);
+ if (service == null) {
+ continue;
+ }
+ return tryTransformWithProvider(initParams, transformParts, transform.needToSet,
+ service);
}
- return tryTransformWithProvider(transformParts, type, service);
- }
- ArrayList<Provider.Service> services = ENGINE.getServices(transform);
- if (services == null || services.isEmpty()) {
- return null;
- }
- boolean keySupported = false;
- for (Provider.Service service : services) {
- if (key == null || service.supportsParameter(key)) {
- keySupported = true;
- Engine.SpiAndProvider sap = tryTransformWithProvider(transformParts, type, service);
- if (sap != null) {
- return sap;
+ ArrayList<Provider.Service> services = ENGINE.getServices(transform.name);
+ if (services == null || services.isEmpty()) {
+ continue;
+ }
+ for (Provider.Service service : services) {
+ if (initParams == null || initParams.key == null
+ || service.supportsParameter(initParams.key)) {
+ try {
+ Engine.SpiAndProvider sap = tryTransformWithProvider(initParams,
+ transformParts, transform.needToSet, service);
+ if (sap != null) {
+ return sap;
+ }
+ } catch (Exception e) {
+ if (cause == null) {
+ cause = e;
+ }
+ }
}
}
}
- if (!keySupported) {
- throw new InvalidKeyException("No provider supports the provided key");
+ if (cause instanceof InvalidKeyException) {
+ throw (InvalidKeyException) cause;
+ } else if (cause instanceof InvalidAlgorithmParameterException) {
+ throw (InvalidAlgorithmParameterException) cause;
+ } else if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ } else if (cause != null) {
+ throw new InvalidKeyException("No provider can be initialized with given key", cause);
+ } else if (initParams == null || initParams.key == null) {
+ return null;
+ } else {
+ // Since the key is not null, a suitable provider exists,
+ // and it is an InvalidKeyException.
+ throw new InvalidKeyException("No provider offers " + transformation + " for "
+ + initParams.key.getAlgorithm() + " key of class "
+ + initParams.key.getClass().getName() + " and export format "
+ + initParams.key.getFormat());
}
- return null;
}
- private static Engine.SpiAndProvider tryTransformWithProvider(String[] transformParts,
- NeedToSet type, Provider.Service service) {
+ /**
+ * Tries to initialize the {@code Cipher} from a given {@code service}. If
+ * initialization is successful, the initialized {@code spi} is returned. If
+ * the {@code service} cannot be initialized with the specified
+ * {@code initParams}, then it's expected to throw
+ * {@code InvalidKeyException} or {@code InvalidAlgorithmParameterException}
+ * as a hint to the caller that it should continue searching for a
+ * {@code Service} that will work.
+ */
+ private static Engine.SpiAndProvider tryTransformWithProvider(InitParams initParams,
+ String[] transformParts, NeedToSet type, Provider.Service service)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
try {
/*
* Check to see if the Cipher even supports the attributes before
@@ -495,9 +588,6 @@
if (sap.spi == null || sap.provider == null) {
return null;
}
- if (!(sap.spi instanceof CipherSpi)) {
- return null;
- }
CipherSpi spi = (CipherSpi) sap.spi;
if (((type == NeedToSet.MODE) || (type == NeedToSet.BOTH))
&& (transformParts[1] != null)) {
@@ -507,6 +597,24 @@
&& (transformParts[2] != null)) {
spi.engineSetPadding(transformParts[2]);
}
+
+ if (initParams != null) {
+ switch (initParams.initType) {
+ case ALGORITHM_PARAMS:
+ spi.engineInit(initParams.opmode, initParams.key, initParams.params,
+ initParams.random);
+ break;
+ case ALGORITHM_PARAM_SPEC:
+ spi.engineInit(initParams.opmode, initParams.key, initParams.spec,
+ initParams.random);
+ break;
+ case KEY:
+ spi.engineInit(initParams.opmode, initParams.key, initParams.random);
+ break;
+ default:
+ throw new AssertionError("This should never be reached");
+ }
+ }
return sap;
} catch (NoSuchAlgorithmException ignored) {
} catch (NoSuchPaddingException ignored) {
@@ -618,6 +726,10 @@
}
+ /**
+ * Checks that the provided {@code mode} is one that is valid for
+ * {@code Cipher}.
+ */
private void checkMode(int mode) {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE && mode != UNWRAP_MODE
&& mode != WRAP_MODE) {
@@ -699,7 +811,12 @@
// FIXME InvalidKeyException
// if keysize exceeds the maximum allowable keysize
// (jurisdiction policy files)
- getSpi(key).engineInit(opmode, key, random);
+ try {
+ getSpi(new InitParams(InitType.KEY, opmode, key, random, null, null));
+ } catch (InvalidAlgorithmParameterException e) {
+ // Should never happen since we only specified the key.
+ throw new ProviderException("Invalid parameters when params == null", e);
+ }
mode = opmode;
}
@@ -789,7 +906,7 @@
// FIXME InvalidAlgorithmParameterException
// cryptographic strength exceed the legal limits
// (jurisdiction policy files)
- getSpi(key).engineInit(opmode, key, params, random);
+ getSpi(new InitParams(InitType.ALGORITHM_PARAM_SPEC, opmode, key, random, params, null));
mode = opmode;
}
@@ -880,7 +997,7 @@
// FIXME InvalidAlgorithmParameterException
// cryptographic strength exceed the legal limits
// (jurisdiction policy files)
- getSpi(key).engineInit(opmode, key, params, random);
+ getSpi(new InitParams(InitType.ALGORITHM_PARAMS, opmode, key, random, null, params));
mode = opmode;
}
@@ -1005,7 +1122,12 @@
// if keysize exceeds the maximum allowable keysize
// (jurisdiction policy files)
final Key key = certificate.getPublicKey();
- getSpi(key).engineInit(opmode, key, random);
+ try {
+ getSpi(new InitParams(InitType.KEY, opmode, key, random, null, null));
+ } catch (InvalidAlgorithmParameterException e) {
+ // Should never happen since we only specified the key.
+ throw new ProviderException("Invalid parameters when params == null", e);
+ }
mode = opmode;
}
diff --git a/luni/src/main/java/libcore/icu/AlphabeticIndex.java b/luni/src/main/java/libcore/icu/AlphabeticIndex.java
deleted file mode 100644
index 322384d..0000000
--- a/luni/src/main/java/libcore/icu/AlphabeticIndex.java
+++ /dev/null
@@ -1,171 +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 libcore.icu;
-
-import java.util.Locale;
-
-/**
- * Exposes icu4c's AlphabeticIndex.
- */
-public final class AlphabeticIndex {
-
- /**
- * Exposes icu4c's ImmutableIndex (new to icu 51). This exposes a read-only,
- * thread safe snapshot view of an AlphabeticIndex at the moment it was
- * created, and allows for random access to buckets by index.
- */
- public static final class ImmutableIndex {
- private long peer;
-
- private ImmutableIndex(long peer) {
- this.peer = peer;
- }
-
- @Override protected synchronized void finalize() throws Throwable {
- try {
- destroy(peer);
- peer = 0;
- } finally {
- super.finalize();
- }
- }
-
- /**
- * Returns the number of the label buckets in this index.
- */
- public int getBucketCount() {
- return getBucketCount(peer);
- }
-
- /**
- * Returns the index of the bucket in which 's' should appear.
- * Function is synchronized because underlying routine walks an iterator
- * whose state is maintained inside the index object.
- */
- public int getBucketIndex(String s) {
- return getBucketIndex(peer, s);
- }
-
- /**
- * Returns the label for the bucket at the given index (as returned by getBucketIndex).
- */
- public String getBucketLabel(int index) {
- return getBucketLabel(peer, index);
- }
-
- private static native int getBucketCount(long peer);
- private static native int getBucketIndex(long peer, String s);
- private static native String getBucketLabel(long peer, int index);
- }
-
- private long peer;
-
- /**
- * Creates a new AlphabeticIndex for the given locale.
- */
- public AlphabeticIndex(Locale locale) {
- peer = create(locale.toString());
- }
-
- @Override protected synchronized void finalize() throws Throwable {
- try {
- destroy(peer);
- peer = 0;
- } finally {
- super.finalize();
- }
- }
-
- /**
- * Returns the max number of the label buckets allowed in this index.
- */
- public synchronized int getMaxLabelCount() {
- return getMaxLabelCount(peer);
- }
-
- /**
- * Sets the max number of the label buckets in this index.
- * (ICU 51 default is 99)
- */
- public synchronized AlphabeticIndex setMaxLabelCount(int count) {
- setMaxLabelCount(peer, count);
- return this;
- }
-
- /**
- * Adds the index characters from the given locale to the index.
- * The labels are added to those that are already in the index;
- * they do not replace the existing index characters.
- * The collation order for this index is not changed;
- * it remains that of the locale that was originally specified
- * when creating this index.
- */
- public synchronized AlphabeticIndex addLabels(Locale locale) {
- addLabels(peer, locale.toString());
- return this;
- }
-
- /**
- * Adds the index characters in the range between the specified start and
- * end code points, inclusive.
- */
- public synchronized AlphabeticIndex addLabelRange(int codePointStart, int codePointEnd) {
- addLabelRange(peer, codePointStart, codePointEnd);
- return this;
- }
-
- /**
- * Returns the number of the label buckets in this index.
- */
- public synchronized int getBucketCount() {
- return getBucketCount(peer);
- }
-
- /**
- * Returns the index of the bucket in which 's' should appear.
- * Function is synchronized because underlying routine walks an iterator
- * whose state is maintained inside the index object.
- */
- public synchronized int getBucketIndex(String s) {
- return getBucketIndex(peer, s);
- }
-
- /**
- * Returns the label for the bucket at the given index (as returned by getBucketIndex).
- */
- public synchronized String getBucketLabel(int index) {
- return getBucketLabel(peer, index);
- }
-
- /**
- * Returns an ImmutableIndex created from this AlphabeticIndex.
- */
- public synchronized ImmutableIndex getImmutableIndex() {
- return new ImmutableIndex(buildImmutableIndex(peer));
- }
-
- private static native long create(String locale);
- private static native void destroy(long peer);
- private static native int getMaxLabelCount(long peer);
- private static native void setMaxLabelCount(long peer, int count);
- private static native void addLabels(long peer, String locale);
- private static native void addLabelRange(long peer, int codePointStart, int codePointEnd);
- private static native int getBucketCount(long peer);
- private static native int getBucketIndex(long peer, String s);
- private static native String getBucketLabel(long peer, int index);
- private static native long buildImmutableIndex(long peer);
-}
diff --git a/luni/src/main/java/libcore/icu/NativeIDN.java b/luni/src/main/java/libcore/icu/NativeIDN.java
deleted file mode 100644
index db93379..0000000
--- a/luni/src/main/java/libcore/icu/NativeIDN.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2010 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 libcore.icu;
-
-public final class NativeIDN {
- public static String toASCII(String s, int flags) {
- return convert(s, flags, true);
- }
-
- public static String toUnicode(String s, int flags) {
- try {
- return convert(s, flags, false);
- } catch (IllegalArgumentException ex) {
- // The RI documentation explicitly states that this method can't fail.
- // ICU4C disagrees, as does the RI in practice.
- // The RI just returns the input string if it can't
- return s;
- }
- }
-
- private static String convert(String s, int flags, boolean toAscii) {
- if (s == null) {
- throw new NullPointerException("s == null");
- }
- return convertImpl(s, flags, toAscii);
- }
- private static native String convertImpl(String s, int flags, boolean toAscii);
-
- private NativeIDN() {}
-}
diff --git a/luni/src/main/java/libcore/icu/NativeNormalizer.java b/luni/src/main/java/libcore/icu/NativeNormalizer.java
deleted file mode 100644
index a5d8da2..0000000
--- a/luni/src/main/java/libcore/icu/NativeNormalizer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 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 libcore.icu;
-
-import java.text.Normalizer.Form;
-
-public final class NativeNormalizer {
- public static boolean isNormalized(CharSequence src, Form form) {
- return isNormalizedImpl(src.toString(), toUNormalizationMode(form));
- }
-
- public static String normalize(CharSequence src, Form form) {
- return normalizeImpl(src.toString(), toUNormalizationMode(form));
- }
-
- private static int toUNormalizationMode(Form form) {
- // Translates Java enum constants to ICU int constants.
- // See UNormalizationMode in "unicode/unorm.h". Stable API since ICU 2.0.
- switch (form) {
- case NFC: return 4;
- case NFD: return 2;
- case NFKC: return 5;
- case NFKD: return 3;
- }
- throw new AssertionError("unknown Normalizer.Form " + form);
- }
-
- private static native String normalizeImpl(String src, int form);
-
- private static native boolean isNormalizedImpl(String src, int form);
-
- private NativeNormalizer() {}
-}
diff --git a/luni/src/main/java/libcore/icu/NativePluralRules.java b/luni/src/main/java/libcore/icu/NativePluralRules.java
deleted file mode 100644
index f9fe74b..0000000
--- a/luni/src/main/java/libcore/icu/NativePluralRules.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2010 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 libcore.icu;
-
-import java.util.Locale;
-
-/**
- * Provides access to ICU's
- * <a href="http://icu-project.org/apiref/icu4c/classPluralRules.html">PluralRules</a> class.
- * This is not necessary for Java API, but is used by frameworks/base's resources system to
- * ease localization of strings to languages with complex grammatical rules regarding number.
- */
-public final class NativePluralRules {
- public static final int ZERO = 0;
- public static final int ONE = 1;
- public static final int TWO = 2;
- public static final int FEW = 3;
- public static final int MANY = 4;
- public static final int OTHER = 5;
-
- private final long address;
-
- private NativePluralRules(long address) {
- this.address = address;
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- finalizeImpl(address);
- } finally {
- super.finalize();
- }
- }
-
- public static NativePluralRules forLocale(Locale locale) {
- return new NativePluralRules(forLocaleImpl(locale.toString()));
- }
-
- /**
- * Returns the constant defined in this class corresponding
- * to the first rule that matches the given value.
- */
- public int quantityForInt(int value) {
- // Pre-L compatibility. http://b/18429565.
- if (value < 0) {
- return OTHER;
- }
- return quantityForIntImpl(address, value);
- }
-
- private static native void finalizeImpl(long address);
- private static native long forLocaleImpl(String localeName);
- private static native int quantityForIntImpl(long address, int value);
-}
diff --git a/luni/src/main/java/libcore/icu/Transliterator.java b/luni/src/main/java/libcore/icu/Transliterator.java
deleted file mode 100644
index 77b5ba7..0000000
--- a/luni/src/main/java/libcore/icu/Transliterator.java
+++ /dev/null
@@ -1,56 +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 libcore.icu;
-
-/**
- * Exposes icu4c's Transliterator.
- */
-public final class Transliterator {
- private long peer;
-
- /**
- * Creates a new Transliterator for the given id.
- */
- public Transliterator(String id) {
- peer = create(id);
- }
-
- @Override protected synchronized void finalize() throws Throwable {
- try {
- destroy(peer);
- peer = 0;
- } finally {
- super.finalize();
- }
- }
-
- /**
- * Returns the ids of all known transliterators.
- */
- public static native String[] getAvailableIDs();
-
- /**
- * Transliterates the specified string.
- */
- public String transliterate(String s) {
- return transliterate(peer, s);
- }
-
- private static native long create(String id);
- private static native void destroy(long peer);
- private static native String transliterate(long peer, String s);
-}
diff --git a/luni/src/main/java/libcore/io/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java
index 532493a..0923c85 100644
--- a/luni/src/main/java/libcore/io/BlockGuardOs.java
+++ b/luni/src/main/java/libcore/io/BlockGuardOs.java
@@ -28,6 +28,7 @@
import java.io.InterruptedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import static android.system.OsConstants.*;
@@ -58,7 +59,7 @@
}
}
- @Override public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException {
+ @Override public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException {
BlockGuard.getThreadPolicy().onNetwork();
return tagSocket(os.accept(fd, peerAddress));
}
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index 5c0c8fd..2dfb418 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -50,7 +50,7 @@
this.os = os;
}
- public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException { return os.accept(fd, peerAddress); }
+ public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException { return os.accept(fd, peerAddress); }
public boolean access(String path, int mode) throws ErrnoException { return os.access(path, mode); }
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); }
@@ -96,6 +96,7 @@
public StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException { return os.getsockoptUcred(fd, level, option); }
public int gettid() { return os.gettid(); }
public int getuid() { return os.getuid(); }
+ public int getxattr(String path, String name, byte[] outValue) throws ErrnoException { return os.getxattr(path, name, outValue); }
public String if_indextoname(int index) { return os.if_indextoname(index); }
public InetAddress inet_pton(int family, String address) { return os.inet_pton(family, address); }
public InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return os.ioctlInetAddress(fd, cmd, interfaceName); }
@@ -131,6 +132,7 @@
public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, buffer, flags, srcAddress); }
public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); }
public void remove(String path) throws ErrnoException { os.remove(path); }
+ public void removexattr(String path, String name) throws ErrnoException { os.removexattr(path, name); }
public void rename(String oldPath, String newPath) throws ErrnoException { os.rename(oldPath, newPath); }
public long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException { return os.sendfile(outFd, inFd, inOffset, byteCount); }
public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return os.sendto(fd, buffer, flags, inetAddress, port); }
@@ -153,6 +155,7 @@
public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException { os.setsockoptLinger(fd, level, option, value); }
public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException { os.setsockoptTimeval(fd, level, option, value); }
public void setuid(int uid) throws ErrnoException { os.setuid(uid); }
+ public void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException { os.setxattr(path, name, value, flags); }
public void shutdown(FileDescriptor fd, int how) throws ErrnoException { os.shutdown(fd, how); }
public FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException { return os.socket(domain, type, protocol); }
public void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException { os.socketpair(domain, type, protocol, fd1, fd2); }
@@ -166,6 +169,7 @@
public void tcsendbreak(FileDescriptor fd, int duration) throws ErrnoException { os.tcsendbreak(fd, duration); }
public int umask(int mask) { return os.umask(mask); }
public StructUtsname uname() { return os.uname(); }
+ public void unlink(String pathname) throws ErrnoException { os.unlink(pathname); }
public void unsetenv(String name) throws ErrnoException { os.unsetenv(name); }
public int waitpid(int pid, MutableInt status, int options) throws ErrnoException { return os.waitpid(pid, status, options); }
public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { return os.write(fd, buffer); }
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 987d331..3cae357 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -41,7 +41,7 @@
import java.nio.ByteBuffer;
public interface Os {
- public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException;
+ public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException;
public boolean access(String path, int mode) throws ErrnoException;
public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
@@ -88,6 +88,7 @@
public StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException;
public int gettid();
public int getuid();
+ public int getxattr(String path, String name, byte[] outValue) throws ErrnoException;
public String if_indextoname(int index);
public InetAddress inet_pton(int family, String address);
public InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException;
@@ -124,6 +125,7 @@
public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException;
public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException;
public void remove(String path) throws ErrnoException;
+ public void removexattr(String path, String name) throws ErrnoException;
public void rename(String oldPath, String newPath) throws ErrnoException;
public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException;
public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException;
@@ -146,6 +148,7 @@
public void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException;
public void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException;
public void setuid(int uid) throws ErrnoException;
+ public void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException;
public void shutdown(FileDescriptor fd, int how) throws ErrnoException;
public FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException;
public void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException;
@@ -159,6 +162,7 @@
public void tcsendbreak(FileDescriptor fd, int duration) throws ErrnoException;
public int umask(int mask);
public StructUtsname uname();
+ public void unlink(String pathname) throws ErrnoException;
public void unsetenv(String name) throws ErrnoException;
public int waitpid(int pid, MutableInt status, int options) throws ErrnoException;
public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException;
diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Posix.java
index d680200..b8bbc85 100644
--- a/luni/src/main/java/libcore/io/Posix.java
+++ b/luni/src/main/java/libcore/io/Posix.java
@@ -44,7 +44,7 @@
public final class Posix implements Os {
Posix() { }
- public native FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException;
+ public native FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException;
public native boolean access(String path, int mode) throws ErrnoException;
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;
@@ -90,6 +90,7 @@
public native StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException;
public native int gettid();
public native int getuid();
+ public native int getxattr(String path, String name, byte[] outValue) throws ErrnoException;
public native String if_indextoname(int index);
public native InetAddress inet_pton(int family, String address);
public native InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException;
@@ -189,6 +190,7 @@
}
private native int recvfromBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException;
public native void remove(String path) throws ErrnoException;
+ public native void removexattr(String path, String name) throws ErrnoException;
public native void rename(String oldPath, String newPath) throws ErrnoException;
public native long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException;
public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException {
@@ -230,6 +232,7 @@
public native void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException;
public native void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException;
public native void setuid(int uid) throws ErrnoException;
+ public native void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException;
public native void shutdown(FileDescriptor fd, int how) throws ErrnoException;
public native FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException;
public native void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException;
@@ -249,6 +252,7 @@
}
private native int umaskImpl(int mask);
public native StructUtsname uname();
+ public native void unlink(String pathname) throws ErrnoException;
public native void unsetenv(String name) throws ErrnoException;
public native int waitpid(int pid, MutableInt status, int options) throws ErrnoException;
public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException {
diff --git a/luni/src/main/java/org/apache/harmony/security/PrivateKeyImpl.java b/luni/src/main/java/org/apache/harmony/security/PrivateKeyImpl.java
deleted file mode 100644
index 47aceb3..0000000
--- a/luni/src/main/java/org/apache/harmony/security/PrivateKeyImpl.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.harmony.security;
-
-import java.security.PrivateKey;
-
-/**
- * PrivateKeyImpl
- */
-public class PrivateKeyImpl implements PrivateKey {
-
- /*
- * @serial
- */
- private static final long serialVersionUID = 7776497482533790279L;
-
- private String algorithm;
-
- private byte[] encoding;
-
- public PrivateKeyImpl(String algorithm) {
- this.algorithm = algorithm;
- }
-
- public String getAlgorithm() {
- return algorithm;
- }
-
- public String getFormat() {
- return "PKCS#8";
- }
-
- public byte[] getEncoded() {
-
- byte[] toReturn = new byte[encoding.length];
- System.arraycopy(encoding, 0, toReturn, 0, encoding.length);
-
- return toReturn;
- }
-
- public void setAlgorithm(String algorithm) {
- this.algorithm = algorithm;
- }
-
- public void setEncoding(byte[] encoding) {
- this.encoding = new byte[encoding.length];
- System.arraycopy(encoding, 0, this.encoding, 0, encoding.length);
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/PublicKeyImpl.java b/luni/src/main/java/org/apache/harmony/security/PublicKeyImpl.java
deleted file mode 100644
index dccc72d..0000000
--- a/luni/src/main/java/org/apache/harmony/security/PublicKeyImpl.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.harmony.security;
-
-import java.security.PublicKey;
-
-
-/**
- * PublicKeyImpl
- */
-public class PublicKeyImpl implements PublicKey {
-
- /**
- * @serial
- */
- private static final long serialVersionUID = 7179022516819534075L;
-
-
- private byte[] encoding;
-
- private String algorithm;
-
-
- public PublicKeyImpl(String algorithm) {
- this.algorithm = algorithm;
- }
-
-
- public String getAlgorithm() {
- return algorithm;
- }
-
-
- public String getFormat() {
- return "X.509";
- }
-
-
- public byte[] getEncoded() {
- byte[] result = new byte[encoding.length];
- System.arraycopy(encoding, 0, result, 0, encoding.length);
- return result;
- }
-
-
- public void setAlgorithm(String algorithm) {
- this.algorithm = algorithm;
- }
-
-
- public void setEncoding(byte[] encoding) {
- this.encoding = new byte[encoding.length];
- System.arraycopy(encoding, 0, this.encoding, 0, encoding.length);
- }
-}
-
diff --git a/luni/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequest.java b/luni/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequest.java
deleted file mode 100644
index 3d36d37..0000000
--- a/luni/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package org.apache.harmony.security.pkcs10;
-
-import org.apache.harmony.security.asn1.ASN1BitString;
-import org.apache.harmony.security.asn1.ASN1Sequence;
-import org.apache.harmony.security.asn1.ASN1Type;
-import org.apache.harmony.security.asn1.BerInputStream;
-import org.apache.harmony.security.asn1.BitString;
-import org.apache.harmony.security.x509.AlgorithmIdentifier;
-
-/**
- * The class implements the ASN.1 DER encoding and decoding of the PKCS#10
- * Certificate Signing Request (CSR). Its ASN notation is as follows:
- *
- * CertificationRequest ::= SEQUENCE {
- * certificationRequestInfo CertificationRequestInfo,
- * signatureAlgorithm SignatureAlgorithmIdentifier,
- * signature Signature
- * }
- *
- * SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
- *
- * Signature ::= BIT STRING
- */
-public final class CertificationRequest {
-
- /** the value of certificationRequestInfo field of the structure */
- private CertificationRequestInfo info;
-
- /** the value of signatureAlgorithm field of the structure */
- private AlgorithmIdentifier algId;
-
- /** the value of signature field of the structure */
- private byte[] signature;
-
- /** the ASN.1 encoded form of CertificationRequest */
- private byte[] encoding;
-
- public CertificationRequest(CertificationRequestInfo info,
- AlgorithmIdentifier algId, byte[] signature) {
- this.info = info;
- this.algId = algId;
- this.signature = signature.clone();
- }
-
- private CertificationRequest(CertificationRequestInfo info,
- AlgorithmIdentifier algId, byte[] signature, byte[] encoding) {
- this(info, algId, signature);
- this.encoding = encoding;
- }
-
- public CertificationRequestInfo getInfo() {
- return info;
- }
-
- public byte[] getSignature() {
- byte[] result = new byte[signature.length];
- System.arraycopy(signature, 0, result, 0, signature.length);
- return result;
- }
-
- /**
- * Returns ASN.1 encoded form of this CertificationRequest value.
- * @return a byte array containing ASN.1 encode form.
- */
- public byte[] getEncoded() {
- if (encoding == null) {
- encoding = CertificationRequest.ASN1.encode(this);
- }
- return encoding;
- }
-
- public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
- CertificationRequestInfo.ASN1, // info
- AlgorithmIdentifier.ASN1, // signatureAlgorithm
- ASN1BitString.getInstance() }) // signature
- {
-
- public Object getDecodedObject(BerInputStream in) {
- Object[] values = (Object[]) in.content;
- return new CertificationRequest(
- (CertificationRequestInfo) values[0],
- (AlgorithmIdentifier) values[1],
- ((BitString) values[2]).bytes,
- in.getEncoded());
- }
-
- protected void getValues(Object object, Object[] values) {
- CertificationRequest certReq = (CertificationRequest) object;
- values[0] = certReq.info;
- values[1] = certReq.algId;
- values[2] = new BitString(certReq.signature, 0);
- }
- };
-}
-
diff --git a/luni/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequestInfo.java b/luni/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequestInfo.java
deleted file mode 100644
index d13f952..0000000
--- a/luni/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequestInfo.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package org.apache.harmony.security.pkcs10;
-
-import java.util.List;
-import javax.security.auth.x500.X500Principal;
-import org.apache.harmony.security.asn1.ASN1Implicit;
-import org.apache.harmony.security.asn1.ASN1Integer;
-import org.apache.harmony.security.asn1.ASN1Sequence;
-import org.apache.harmony.security.asn1.ASN1SetOf;
-import org.apache.harmony.security.asn1.ASN1Type;
-import org.apache.harmony.security.asn1.BerInputStream;
-import org.apache.harmony.security.x501.AttributeTypeAndValue;
-import org.apache.harmony.security.x501.Name;
-import org.apache.harmony.security.x509.SubjectPublicKeyInfo;
-
-/**
- * CertificationRequestInfo ::= SEQUENCE {
- * version Version,
- * subject Name,
- * subjectPublicKeyInfo SubjectPublicKeyInfo,
- * attributes [0] IMPLICIT Attributes }
- *
- * Version ::= INTEGER
- *
- * Attributes ::= SET OF Attribute
- */
-public final class CertificationRequestInfo {
- private final int version;
-
- /** the value of subject field of the structure */
- private final Name subject;
-
- /** the value of subjectPublicKeyInfo field of the structure */
- private final SubjectPublicKeyInfo subjectPublicKeyInfo;
-
- /** the value of attributes field of the structure */
- private final List<?> attributes;
-
- /** the ASN.1 encoded form of CertificationRequestInfo */
- private byte[] encoding;
-
- private CertificationRequestInfo(int version, Name subject,
- SubjectPublicKeyInfo subjectPublicKeyInfo, List<?> attributes, byte [] encoding) {
- this.version = version;
- this.subject = subject;
- this.subjectPublicKeyInfo = subjectPublicKeyInfo;
- this.attributes = attributes;
- this.encoding = encoding;
- }
-
- public Name getSubject() {
- return subject;
- }
-
- public int getVersion() {
- return version;
- }
-
- /**
- * Returns ASN.1 encoded form of this CertificationRequestInfo.
- * @return a byte array containing ASN.1 encode form.
- */
- public byte[] getEncoded() {
- if (encoding == null) {
- encoding = ASN1.encode(this);
- }
- return encoding;
- }
-
- @Override public String toString() {
- StringBuilder res = new StringBuilder();
- res.append("-- CertificationRequestInfo:");
- res.append("\n version: ");
- res.append(version);
- res.append("\n subject: ");
- res.append(subject.getName(X500Principal.CANONICAL));
- res.append("\n subjectPublicKeyInfo: ");
- res.append("\n\t algorithm: ");
- res.append(subjectPublicKeyInfo.getAlgorithmIdentifier().getAlgorithm());
- res.append("\n\t public key: ").append(subjectPublicKeyInfo.getPublicKey());
- res.append("\n attributes: ");
- if (attributes != null) {
- res.append(attributes.toString());
- } else {
- res.append("none");
- }
- res.append("\n-- CertificationRequestInfo End\n");
- return res.toString();
- }
-
- public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
- ASN1Integer.getInstance(), // version
- Name.ASN1, // subject
- SubjectPublicKeyInfo.ASN1, // subjectPublicKeyInfo
- new ASN1Implicit(0, new ASN1SetOf(
- AttributeTypeAndValue.ASN1)) // attributes
- }) {
-
- @Override protected Object getDecodedObject(BerInputStream in) {
- Object[] values = (Object[]) in.content;
- return new CertificationRequestInfo(
- ASN1Integer.toIntValue(values[0]),
- (Name) values[1],
- (SubjectPublicKeyInfo) values[2],
- (List<?>) values[3],
- in.getEncoded());
- }
-
- @Override protected void getValues(Object object, Object[] values) {
- CertificationRequestInfo certReqInfo = (CertificationRequestInfo) object;
- values[0] = ASN1Integer.fromIntValue(certReqInfo.version);
- values[1] = certReqInfo.subject;
- values[2] = certReqInfo.subjectPublicKeyInfo;
- values[3] = certReqInfo.attributes;
- }
- };
-}
-
diff --git a/luni/src/main/java/org/apache/harmony/security/pkcs8/PrivateKeyInfo.java b/luni/src/main/java/org/apache/harmony/security/pkcs8/PrivateKeyInfo.java
deleted file mode 100644
index 400bf86..0000000
--- a/luni/src/main/java/org/apache/harmony/security/pkcs8/PrivateKeyInfo.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.harmony.security.pkcs8;
-
-import java.util.List;
-import org.apache.harmony.security.asn1.ASN1Implicit;
-import org.apache.harmony.security.asn1.ASN1Integer;
-import org.apache.harmony.security.asn1.ASN1OctetString;
-import org.apache.harmony.security.asn1.ASN1Sequence;
-import org.apache.harmony.security.asn1.ASN1SetOf;
-import org.apache.harmony.security.asn1.ASN1Type;
-import org.apache.harmony.security.asn1.BerInputStream;
-import org.apache.harmony.security.x501.AttributeTypeAndValue;
-import org.apache.harmony.security.x509.AlgorithmIdentifier;
-
-/**
- * The class implements the ASN.1 DER encoding and decoding of the PKCS#8
- * PrivateKeyInfo having the following ASN.1 notation:
- *
- * PrivateKeyInfo ::= SEQUENCE {
- * version Version,
- * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
- * privateKey PrivateKey,
- * attributes [0] IMPLICIT Attributes OPTIONAL }
- *
- * Version ::= INTEGER
- *
- * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
- *
- * PrivateKey ::= OCTET STRING
- *
- * Attributes ::= SET OF Attribute
- */
-public final class PrivateKeyInfo {
- private final int version;
- private final AlgorithmIdentifier privateKeyAlgorithm;
- private final byte[] privateKey;
- private final List<?> attributes;
- private byte[] encoding;
-
- public PrivateKeyInfo(int version, AlgorithmIdentifier privateKeyAlgorithm,
- byte[] privateKey, List attributes) {
- this.version = version;
- this.privateKeyAlgorithm = privateKeyAlgorithm;
- this.privateKey = privateKey;
- this.attributes = attributes;
- }
-
- private PrivateKeyInfo(int version,
- AlgorithmIdentifier privateKeyAlgorithm, byte[] privateKey,
- List attributes, byte[] encoding) {
- this(version, privateKeyAlgorithm, privateKey, attributes);
- this.encoding = encoding;
- }
-
- public int getVersion() {
- return version;
- }
-
- public AlgorithmIdentifier getAlgorithmIdentifier() {
- return privateKeyAlgorithm;
- }
-
- public List getAttributes() {
- return attributes;
- }
-
- /**
- * Returns the OCTET STRING.
- */
- public byte[] getPrivateKey() {
- return privateKey;
- }
-
- /**
- * Returns ASN.1 encoded form of this PrivateKeyInfo.
- */
- public byte[] getEncoded() {
- if (encoding == null) {
- encoding = ASN1.encode(this);
- }
- return encoding;
- }
-
- public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
-
- ASN1Integer.getInstance(), // version
- AlgorithmIdentifier.ASN1, // AlgorithmIdentifier
- ASN1OctetString.getInstance(), // privateKey
-
- new ASN1Implicit(0, new ASN1SetOf(AttributeTypeAndValue.ASN1)) // attributes
- }) {
-
- {
- setOptional(3); // attributes are OPTIONAL
- }
-
- protected Object getDecodedObject(BerInputStream in) {
- Object[] values = (Object[]) in.content;
- return new PrivateKeyInfo(ASN1Integer.toIntValue(values[0]),
- (AlgorithmIdentifier) values[1], (byte[]) values[2],
- (List) values[3], in.getEncoded());
- }
-
- protected void getValues(Object object, Object[] values) {
- PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo) object;
- values[0] = ASN1Integer.fromIntValue(privateKeyInfo.version);
- values[1] = privateKeyInfo.privateKeyAlgorithm;
- values[2] = privateKeyInfo.privateKey;
- values[3] = privateKeyInfo.attributes;
- }
- };
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/CryptoProvider.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/CryptoProvider.java
deleted file mode 100644
index ad5ac7d..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/CryptoProvider.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.provider.crypto;
-
-import java.security.Provider;
-
-/**
- * Implementation of Provider for SecureRandom. The implementation supports the
- * "SHA1PRNG" algorithm described in JavaTM Cryptography Architecture, API
- * Specification & Reference
- */
-
-public final class CryptoProvider extends Provider {
-
- private static final long serialVersionUID = 7991202868423459598L;
-
- /**
- * Creates a Provider and puts parameters
- */
- public CryptoProvider() {
- super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
-
- put("SecureRandom.SHA1PRNG",
- "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
- put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1Constants.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1Constants.java
deleted file mode 100644
index fc6a847..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1Constants.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
-* @author Yuri A. Kropachev
-* @version $Revision$
-*/
-
-
-package org.apache.harmony.security.provider.crypto;
-
-
-/**
- * This interface contains : <BR>
- * - a set of constant values, H0-H4, defined in "SECURE HASH STANDARD", FIPS PUB 180-2 ;<BR>
- * - implementation constant values to use in classes using SHA-1 algorithm. <BR>
- */
-public final class SHA1Constants {
- private SHA1Constants() {
- }
-
- /**
- * constant defined in "SECURE HASH STANDARD"
- */
- public static final int H0 = 0x67452301;
-
-
- /**
- * constant defined in "SECURE HASH STANDARD"
- */
- public static final int H1 = 0xEFCDAB89;
-
-
- /**
- * constant defined in "SECURE HASH STANDARD"
- */
- public static final int H2 = 0x98BADCFE;
-
-
- /**
- * constant defined in "SECURE HASH STANDARD"
- */
- public static final int H3 = 0x10325476;
-
-
- /**
- * constant defined in "SECURE HASH STANDARD"
- */
- public static final int H4 = 0xC3D2E1F0;
-
-
- /**
- * offset in buffer to store number of bytes in 0-15 word frame
- */
- public static final int BYTES_OFFSET = 81;
-
-
- /**
- * offset in buffer to store current hash value
- */
- public static final int HASH_OFFSET = 82;
-
-
- /**
- * # of bytes in H0-H4 words; <BR>
- * in this implementation # is set to 20 (in general # varies from 1 to 20)
- */
- public static final int DIGEST_LENGTH = 20;
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1Impl.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1Impl.java
deleted file mode 100644
index 57b9005..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1Impl.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
-* @author Yuri A. Kropachev
-* @version $Revision$
-*/
-
-
-package org.apache.harmony.security.provider.crypto;
-
-import static org.apache.harmony.security.provider.crypto.SHA1Constants.*;
-
-/**
- * This class contains methods providing SHA-1 functionality to use in classes. <BR>
- * The methods support the algorithm described in "SECURE HASH STANDARD", FIPS PUB 180-2, <BR>
- * "http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf" <BR>
- * <BR>
- * The class contains two package level access methods, -
- * "void updateHash(int[], byte[], int, int)" and "void computeHash(int[])", -
- * performing the following operations. <BR>
- * <BR>
- * The "updateHash(..)" method appends new bytes to existing ones
- * within limit of a frame of 64 bytes (16 words).
- * Once a length of accumulated bytes reaches the limit
- * the "computeHash(int[])" method is invoked on the frame to compute updated hash,
- * and the number of bytes in the frame is set to 0.
- * Thus, after appending all bytes, the frame contain only those bytes
- * that were not used in computing final hash value yet. <BR>
- * <BR>
- * The "computeHash(..)" method generates a 160 bit hash value using
- * a 512 bit message stored in first 16 words of int[] array argument and
- * current hash value stored in five words, beginning HASH_OFFSET, of the array argument.
- * Computation is done according to SHA-1 algorithm. <BR>
- * <BR>
- * The resulting hash value replaces the previous hash value in the array;
- * original bits of the message are not preserved.
- */
-public class SHA1Impl {
-
-
- /**
- * The method generates a 160 bit hash value using
- * a 512 bit message stored in first 16 words of int[] array argument and
- * current hash value stored in five words, beginning OFFSET+1, of the array argument.
- * Computation is done according to SHA-1 algorithm.
- *
- * The resulting hash value replaces the previous hash value in the array;
- * original bits of the message are not preserved.
- *
- * No checks on argument supplied, that is,
- * a calling method is responsible for such checks.
- * In case of incorrect array passed to the method
- * either NPE or IndexOutOfBoundException gets thrown by JVM.
- *
- * @params
- * arrW - integer array; arrW.length >= (BYTES_OFFSET+6); <BR>
- * only first (BYTES_OFFSET+6) words are used
- */
- static void computeHash(int[] arrW) {
-
- int a = arrW[HASH_OFFSET ];
- int b = arrW[HASH_OFFSET +1];
- int c = arrW[HASH_OFFSET +2];
- int d = arrW[HASH_OFFSET +3];
- int e = arrW[HASH_OFFSET +4];
-
- int temp;
-
- // In this implementation the "d. For t = 0 to 79 do" loop
- // is split into four loops. The following constants:
- // K = 5A827999 0 <= t <= 19
- // K = 6ED9EBA1 20 <= t <= 39
- // K = 8F1BBCDC 40 <= t <= 59
- // K = CA62C1D6 60 <= t <= 79
- // are hex literals in the loops.
-
- for ( int t = 16; t < 80 ; t++ ) {
-
- temp = arrW[t-3] ^ arrW[t-8] ^ arrW[t-14] ^ arrW[t-16];
- arrW[t] = ( temp<<1 ) | ( temp>>>31 );
- }
-
- for ( int t = 0 ; t < 20 ; t++ ) {
-
- temp = ( ( a<<5 ) | ( a>>>27 ) ) +
- ( ( b & c) | ((~b) & d) ) +
- ( e + arrW[t] + 0x5A827999 ) ;
- e = d;
- d = c;
- c = ( b<<30 ) | ( b>>>2 ) ;
- b = a;
- a = temp;
- }
- for ( int t = 20 ; t < 40 ; t++ ) {
-
- temp = ((( a<<5 ) | ( a>>>27 ))) + (b ^ c ^ d) + (e + arrW[t] + 0x6ED9EBA1) ;
- e = d;
- d = c;
- c = ( b<<30 ) | ( b>>>2 ) ;
- b = a;
- a = temp;
- }
- for ( int t = 40 ; t < 60 ; t++ ) {
-
- temp = (( a<<5 ) | ( a>>>27 )) + ((b & c) | (b & d) | (c & d)) +
- (e + arrW[t] + 0x8F1BBCDC) ;
- e = d;
- d = c;
- c = ( b<<30 ) | ( b>>>2 ) ;
- b = a;
- a = temp;
- }
- for ( int t = 60 ; t < 80 ; t++ ) {
-
- temp = ((( a<<5 ) | ( a>>>27 ))) + (b ^ c ^ d) + (e + arrW[t] + 0xCA62C1D6) ;
- e = d;
- d = c;
- c = ( b<<30 ) | ( b>>>2 ) ;
- b = a;
- a = temp;
- }
-
- arrW[HASH_OFFSET ] += a;
- arrW[HASH_OFFSET +1] += b;
- arrW[HASH_OFFSET +2] += c;
- arrW[HASH_OFFSET +3] += d;
- arrW[HASH_OFFSET +4] += e;
- }
-
- /**
- * The method appends new bytes to existing ones
- * within limit of a frame of 64 bytes (16 words).
- *
- * Once a length of accumulated bytes reaches the limit
- * the "computeHash(int[])" method is invoked on the array to compute updated hash,
- * and the number of bytes in the frame is set to 0.
- * Thus, after appending all bytes, the array contain only those bytes
- * that were not used in computing final hash value yet.
- *
- * No checks on arguments passed to the method, that is,
- * a calling method is responsible for such checks.
- *
- * @params
- * intArray - int array containing bytes to which to append;
- * intArray.length >= (BYTES_OFFSET+6)
- * @params
- * byteInput - array of bytes to use for the update
- * @params
- * from - the offset to start in the "byteInput" array
- * @params
- * to - a number of the last byte in the input array to use,
- * that is, for first byte "to"==0, for last byte "to"==input.length-1
- */
- static void updateHash(int[] intArray, byte[] byteInput, int fromByte, int toByte) {
-
- // As intArray contains a packed bytes
- // the buffer's index is in the intArray[BYTES_OFFSET] element
-
- int index = intArray[BYTES_OFFSET];
- int i = fromByte;
- int maxWord;
- int nBytes;
-
- int wordIndex = index >>2;
- int byteIndex = index & 0x03;
-
- intArray[BYTES_OFFSET] = ( index + toByte - fromByte + 1 ) & 077 ;
-
- // In general case there are 3 stages :
- // - appending bytes to non-full word,
- // - writing 4 bytes into empty words,
- // - writing less than 4 bytes in last word
-
- if ( byteIndex != 0 ) { // appending bytes in non-full word (as if)
-
- for ( ; ( i <= toByte ) && ( byteIndex < 4 ) ; i++ ) {
- intArray[wordIndex] |= ( byteInput[i] & 0xFF ) << ((3 - byteIndex)<<3) ;
- byteIndex++;
- }
- if ( byteIndex == 4 ) {
- wordIndex++;
- if ( wordIndex == 16 ) { // intArray is full, computing hash
-
- computeHash(intArray);
- wordIndex = 0;
- }
- }
- if ( i > toByte ) { // all input bytes appended
- return ;
- }
- }
-
- // writing full words
-
- maxWord = (toByte - i + 1) >> 2; // # of remaining full words, may be "0"
- for ( int k = 0; k < maxWord ; k++ ) {
-
- intArray[wordIndex] = ( ((int) byteInput[i ] & 0xFF) <<24 ) |
- ( ((int) byteInput[i +1] & 0xFF) <<16 ) |
- ( ((int) byteInput[i +2] & 0xFF) <<8 ) |
- ( ((int) byteInput[i +3] & 0xFF) ) ;
- i += 4;
- wordIndex++;
-
- if ( wordIndex < 16 ) { // buffer is not full yet
- continue;
- }
- computeHash(intArray); // buffer is full, computing hash
- wordIndex = 0;
- }
-
- // writing last incomplete word
- // after writing free byte positions are set to "0"s
-
- nBytes = toByte - i +1;
- if ( nBytes != 0 ) {
-
- int w = ((int) byteInput[i] & 0xFF) <<24 ;
-
- if ( nBytes != 1 ) {
- w |= ((int) byteInput[i +1] & 0xFF) <<16 ;
- if ( nBytes != 2) {
- w |= ((int) byteInput[i +2] & 0xFF) <<8 ;
- }
- }
- intArray[wordIndex] = w;
- }
-
- return ;
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java b/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java
deleted file mode 100644
index 5c0e328..0000000
--- a/luni/src/main/java/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.harmony.security.provider.crypto;
-
-import dalvik.system.BlockGuard;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.security.InvalidParameterException;
-import java.security.ProviderException;
-import java.security.SecureRandomSpi;
-import libcore.io.Streams;
-import libcore.util.EmptyArray;
-
-import static org.apache.harmony.security.provider.crypto.SHA1Constants.*;
-
-/**
- * This class extends the SecureRandomSpi class implementing all its abstract methods.
- *
- * <p>To generate pseudo-random bits, the implementation uses technique described in
- * the "Random Number Generator (RNG) algorithms" section, Appendix A,
- * JavaTM Cryptography Architecture, API Specification & Reference.
- */
-public class SHA1PRNG_SecureRandomImpl extends SecureRandomSpi implements Serializable {
-
- private static final long serialVersionUID = 283736797212159675L;
-
- private static FileInputStream devURandom;
- static {
- try {
- devURandom = new FileInputStream(new File("/dev/urandom"));
- } catch (IOException ex) {
- throw new RuntimeException(ex);
- }
- }
-
- // constants to use in expressions operating on bytes in int and long variables:
- // END_FLAGS - final bytes in words to append to message;
- // see "ch.5.1 Padding the Message, FIPS 180-2"
- // RIGHT1 - shifts to right for left half of long
- // RIGHT2 - shifts to right for right half of long
- // LEFT - shifts to left for bytes
- // MASK - mask to select counter's bytes after shift to right
-
- private static final int[] END_FLAGS = { 0x80000000, 0x800000, 0x8000, 0x80 };
-
- private static final int[] RIGHT1 = { 0, 40, 48, 56 };
-
- private static final int[] RIGHT2 = { 0, 8, 16, 24 };
-
- private static final int[] LEFT = { 0, 24, 16, 8 };
-
- private static final int[] MASK = { 0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF,
- 0x000000FF };
-
- // HASHBYTES_TO_USE defines # of bytes returned by "computeHash(byte[])"
- // to use to form byte array returning by the "nextBytes(byte[])" method
- // Note, that this implementation uses more bytes than it is defined
- // in the above specification.
- private static final int HASHBYTES_TO_USE = 20;
-
- // value of 16 defined in the "SECURE HASH STANDARD", FIPS PUB 180-2
- private static final int FRAME_LENGTH = 16;
-
- // miscellaneous constants defined in this implementation:
- // COUNTER_BASE - initial value to set to "counter" before computing "nextBytes(..)";
- // note, that the exact value is not defined in STANDARD
- // HASHCOPY_OFFSET - offset for copy of current hash in "copies" array
- // EXTRAFRAME_OFFSET - offset for extra frame in "copies" array;
- // as the extra frame follows the current hash frame,
- // EXTRAFRAME_OFFSET is equal to length of current hash frame
- // FRAME_OFFSET - offset for frame in "copies" array
- // MAX_BYTES - maximum # of seed bytes processing which doesn't require extra frame
- // see (1) comments on usage of "seed" array below and
- // (2) comments in "engineNextBytes(byte[])" method
- //
- // UNDEFINED - three states of engine; initially its state is "UNDEFINED"
- // SET_SEED call to "engineSetSeed" sets up "SET_SEED" state,
- // NEXT_BYTES call to "engineNextByte" sets up "NEXT_BYTES" state
-
- private static final int COUNTER_BASE = 0;
-
- private static final int HASHCOPY_OFFSET = 0;
-
- private static final int EXTRAFRAME_OFFSET = 5;
-
- private static final int FRAME_OFFSET = 21;
-
- private static final int MAX_BYTES = 48;
-
- private static final int UNDEFINED = 0;
-
- private static final int SET_SEED = 1;
-
- private static final int NEXT_BYTES = 2;
-
- private static SHA1PRNG_SecureRandomImpl myRandom;
-
- // Structure of "seed" array:
- // - 0-79 - words for computing hash
- // - 80 - unused
- // - 81 - # of seed bytes in current seed frame
- // - 82-86 - 5 words, current seed hash
- private transient int[] seed;
-
- // total length of seed bytes, including all processed
- private transient long seedLength;
-
- // Structure of "copies" array
- // - 0-4 - 5 words, copy of current seed hash
- // - 5-20 - extra 16 words frame;
- // is used if final padding exceeds 512-bit length
- // - 21-36 - 16 word frame to store a copy of remaining bytes
- private transient int[] copies;
-
- // ready "next" bytes; needed because words are returned
- private transient byte[] nextBytes;
-
- // index of used bytes in "nextBytes" array
- private transient int nextBIndex;
-
- // variable required according to "SECURE HASH STANDARD"
- private transient long counter;
-
- // contains int value corresponding to engine's current state
- private transient int state;
-
- // The "seed" array is used to compute both "current seed hash" and "next bytes".
- //
- // As the "SHA1" algorithm computes a hash of entire seed by splitting it into
- // a number of the 512-bit length frames (512 bits = 64 bytes = 16 words),
- // "current seed hash" is a hash (5 words, 20 bytes) for all previous full frames;
- // remaining bytes are stored in the 0-15 word frame of the "seed" array.
- //
- // As for calculating "next bytes",
- // both remaining bytes and "current seed hash" are used,
- // to preserve the latter for following "setSeed(..)" commands,
- // the following technique is used:
- // - upon getting "nextBytes(byte[])" invoked, single or first in row,
- // which requires computing new hash, that is,
- // there is no more bytes remaining from previous "next bytes" computation,
- // remaining bytes are copied into the 21-36 word frame of the "copies" array;
- // - upon getting "setSeed(byte[])" invoked, single or first in row,
- // remaining bytes are copied back.
-
- /**
- * Creates object and sets implementation variables to their initial values
- */
- public SHA1PRNG_SecureRandomImpl() {
-
- seed = new int[HASH_OFFSET + EXTRAFRAME_OFFSET];
- seed[HASH_OFFSET] = H0;
- seed[HASH_OFFSET + 1] = H1;
- seed[HASH_OFFSET + 2] = H2;
- seed[HASH_OFFSET + 3] = H3;
- seed[HASH_OFFSET + 4] = H4;
-
- seedLength = 0;
- copies = new int[2 * FRAME_LENGTH + EXTRAFRAME_OFFSET];
- nextBytes = new byte[DIGEST_LENGTH];
- nextBIndex = HASHBYTES_TO_USE;
- counter = COUNTER_BASE;
- state = UNDEFINED;
- }
-
- /*
- * The method invokes the SHA1Impl's "updateHash(..)" method
- * to update current seed frame and
- * to compute new intermediate hash value if the frame is full.
- *
- * After that it computes a length of whole seed.
- */
- private void updateSeed(byte[] bytes) {
-
- // on call: "seed" contains current bytes and current hash;
- // on return: "seed" contains new current bytes and possibly new current hash
- // if after adding, seed bytes overfill its buffer
- SHA1Impl.updateHash(seed, bytes, 0, bytes.length - 1);
-
- seedLength += bytes.length;
- }
-
- /**
- * Changes current seed by supplementing a seed argument to the current seed,
- * if this already set;
- * the argument is used as first seed otherwise. <BR>
- *
- * The method overrides "engineSetSeed(byte[])" in class SecureRandomSpi.
- *
- * @param
- * seed - byte array
- * @throws
- * NullPointerException - if null is passed to the "seed" argument
- */
- protected synchronized void engineSetSeed(byte[] seed) {
-
- if (seed == null) {
- throw new NullPointerException("seed == null");
- }
-
- if (state == NEXT_BYTES) { // first setSeed after NextBytes; restoring hash
- System.arraycopy(copies, HASHCOPY_OFFSET, this.seed, HASH_OFFSET,
- EXTRAFRAME_OFFSET);
- }
- state = SET_SEED;
-
- if (seed.length != 0) {
- updateSeed(seed);
- }
- }
-
- /**
- * Returns a required number of random bytes. <BR>
- *
- * The method overrides "engineGenerateSeed (int)" in class SecureRandomSpi. <BR>
- *
- * @param
- * numBytes - number of bytes to return; should be >= 0.
- * @return
- * byte array containing bits in order from left to right
- * @throws
- * InvalidParameterException - if numBytes < 0
- */
- protected synchronized byte[] engineGenerateSeed(int numBytes) {
-
- byte[] myBytes; // byte[] for bytes returned by "nextBytes()"
-
- if (numBytes < 0) {
- throw new NegativeArraySizeException(Integer.toString(numBytes));
- }
- if (numBytes == 0) {
- return EmptyArray.BYTE;
- }
-
- if (myRandom == null) {
- myRandom = new SHA1PRNG_SecureRandomImpl();
- myRandom.engineSetSeed(getRandomBytes(DIGEST_LENGTH));
- }
-
- myBytes = new byte[numBytes];
- myRandom.engineNextBytes(myBytes);
-
- return myBytes;
- }
-
- /**
- * Writes random bytes into an array supplied.
- * Bits in a byte are from left to right. <BR>
- *
- * To generate random bytes, the "expansion of source bits" method is used,
- * that is,
- * the current seed with a 64-bit counter appended is used to compute new bits.
- * The counter is incremented by 1 for each 20-byte output. <BR>
- *
- * The method overrides engineNextBytes in class SecureRandomSpi.
- *
- * @param
- * bytes - byte array to be filled in with bytes
- * @throws
- * NullPointerException - if null is passed to the "bytes" argument
- */
- protected synchronized void engineNextBytes(byte[] bytes) {
-
- int i, n;
-
- long bits; // number of bits required by Secure Hash Standard
- int nextByteToReturn; // index of ready bytes in "bytes" array
- int lastWord; // index of last word in frame containing bytes
- final int extrabytes = 7;// # of bytes to add in order to computer # of 8 byte words
-
- if (bytes == null) {
- throw new NullPointerException("bytes == null");
- }
-
- lastWord = seed[BYTES_OFFSET] == 0 ? 0
- : (seed[BYTES_OFFSET] + extrabytes) >> 3 - 1;
-
- if (state == UNDEFINED) {
-
- // no seed supplied by user, hence it is generated thus randomizing internal state
- updateSeed(getRandomBytes(DIGEST_LENGTH));
- nextBIndex = HASHBYTES_TO_USE;
-
- // updateSeed(...) updates where the last word of the seed is, so we
- // have to read it again.
- lastWord = seed[BYTES_OFFSET] == 0 ? 0
- : (seed[BYTES_OFFSET] + extrabytes) >> 3 - 1;
-
- } else if (state == SET_SEED) {
-
- System.arraycopy(seed, HASH_OFFSET, copies, HASHCOPY_OFFSET,
- EXTRAFRAME_OFFSET);
-
- // possible cases for 64-byte frame:
- //
- // seed bytes < 48 - remaining bytes are enough for all, 8 counter bytes,
- // 0x80, and 8 seedLength bytes; no extra frame required
- // 48 < seed bytes < 56 - remaining 9 bytes are for 0x80 and 8 counter bytes
- // extra frame contains only seedLength value at the end
- // seed bytes > 55 - extra frame contains both counter's bytes
- // at the beginning and seedLength value at the end;
- // note, that beginning extra bytes are not more than 8,
- // that is, only 2 extra words may be used
-
- // no need to set to "0" 3 words after "lastWord" and
- // more than two words behind frame
- for (i = lastWord + 3; i < FRAME_LENGTH + 2; i++) {
- seed[i] = 0;
- }
-
- bits = (seedLength << 3) + 64; // transforming # of bytes into # of bits
-
- // putting # of bits into two last words (14,15) of 16 word frame in
- // seed or copies array depending on total length after padding
- if (seed[BYTES_OFFSET] < MAX_BYTES) {
- seed[14] = (int) (bits >>> 32);
- seed[15] = (int) (bits & 0xFFFFFFFF);
- } else {
- copies[EXTRAFRAME_OFFSET + 14] = (int) (bits >>> 32);
- copies[EXTRAFRAME_OFFSET + 15] = (int) (bits & 0xFFFFFFFF);
- }
-
- nextBIndex = HASHBYTES_TO_USE; // skipping remaining random bits
- }
- state = NEXT_BYTES;
-
- if (bytes.length == 0) {
- return;
- }
-
- nextByteToReturn = 0;
-
- // possibly not all of HASHBYTES_TO_USE bytes were used previous time
- n = (HASHBYTES_TO_USE - nextBIndex) < (bytes.length - nextByteToReturn) ? HASHBYTES_TO_USE
- - nextBIndex
- : bytes.length - nextByteToReturn;
- if (n > 0) {
- System.arraycopy(nextBytes, nextBIndex, bytes, nextByteToReturn, n);
- nextBIndex += n;
- nextByteToReturn += n;
- }
-
- if (nextByteToReturn >= bytes.length) {
- return; // return because "bytes[]" are filled in
- }
-
- n = seed[BYTES_OFFSET] & 0x03;
- for (;;) {
- if (n == 0) {
-
- seed[lastWord] = (int) (counter >>> 32);
- seed[lastWord + 1] = (int) (counter & 0xFFFFFFFF);
- seed[lastWord + 2] = END_FLAGS[0];
-
- } else {
-
- seed[lastWord] |= (int) ((counter >>> RIGHT1[n]) & MASK[n]);
- seed[lastWord + 1] = (int) ((counter >>> RIGHT2[n]) & 0xFFFFFFFF);
- seed[lastWord + 2] = (int) ((counter << LEFT[n]) | END_FLAGS[n]);
- }
- if (seed[BYTES_OFFSET] > MAX_BYTES) {
- copies[EXTRAFRAME_OFFSET] = seed[FRAME_LENGTH];
- copies[EXTRAFRAME_OFFSET + 1] = seed[FRAME_LENGTH + 1];
- }
-
- SHA1Impl.computeHash(seed);
-
- if (seed[BYTES_OFFSET] > MAX_BYTES) {
-
- System.arraycopy(seed, 0, copies, FRAME_OFFSET, FRAME_LENGTH);
- System.arraycopy(copies, EXTRAFRAME_OFFSET, seed, 0,
- FRAME_LENGTH);
-
- SHA1Impl.computeHash(seed);
- System.arraycopy(copies, FRAME_OFFSET, seed, 0, FRAME_LENGTH);
- }
- counter++;
-
- int j = 0;
- for (i = 0; i < EXTRAFRAME_OFFSET; i++) {
- int k = seed[HASH_OFFSET + i];
- nextBytes[j] = (byte) (k >>> 24); // getting first byte from left
- nextBytes[j + 1] = (byte) (k >>> 16); // getting second byte from left
- nextBytes[j + 2] = (byte) (k >>> 8); // getting third byte from left
- nextBytes[j + 3] = (byte) (k); // getting fourth byte from left
- j += 4;
- }
-
- nextBIndex = 0;
- j = HASHBYTES_TO_USE < (bytes.length - nextByteToReturn) ? HASHBYTES_TO_USE
- : bytes.length - nextByteToReturn;
-
- if (j > 0) {
- System.arraycopy(nextBytes, 0, bytes, nextByteToReturn, j);
- nextByteToReturn += j;
- nextBIndex += j;
- }
-
- if (nextByteToReturn >= bytes.length) {
- break;
- }
- }
- }
-
- private void writeObject(ObjectOutputStream oos) throws IOException {
-
- int[] intData = null;
-
- final int only_hash = EXTRAFRAME_OFFSET;
- final int hashes_and_frame = EXTRAFRAME_OFFSET * 2 + FRAME_LENGTH;
- final int hashes_and_frame_extra = EXTRAFRAME_OFFSET * 2 + FRAME_LENGTH
- * 2;
-
- oos.writeLong(seedLength);
- oos.writeLong(counter);
- oos.writeInt(state);
- oos.writeInt(seed[BYTES_OFFSET]);
-
- int nRemaining = (seed[BYTES_OFFSET] + 3) >> 2; // converting bytes in words
- // result may be 0
- if (state != NEXT_BYTES) {
-
- // either the state is UNDEFINED or previous method was "setSeed(..)"
- // so in "seed[]" to serialize are remaining bytes (seed[0-nRemaining]) and
- // current hash (seed[82-86])
-
- intData = new int[only_hash + nRemaining];
-
- System.arraycopy(seed, 0, intData, 0, nRemaining);
- System.arraycopy(seed, HASH_OFFSET, intData, nRemaining,
- EXTRAFRAME_OFFSET);
-
- } else {
- // previous method was "nextBytes(..)"
- // so, data to serialize are all the above (two first are in "copies" array)
- // and current words in both frame and extra frame (as if)
-
- int offset = 0;
- if (seed[BYTES_OFFSET] < MAX_BYTES) { // no extra frame
-
- intData = new int[hashes_and_frame + nRemaining];
-
- } else { // extra frame is used
-
- intData = new int[hashes_and_frame_extra + nRemaining];
-
- intData[offset] = seed[FRAME_LENGTH];
- intData[offset + 1] = seed[FRAME_LENGTH + 1];
- intData[offset + 2] = seed[FRAME_LENGTH + 14];
- intData[offset + 3] = seed[FRAME_LENGTH + 15];
- offset += 4;
- }
-
- System.arraycopy(seed, 0, intData, offset, FRAME_LENGTH);
- offset += FRAME_LENGTH;
-
- System.arraycopy(copies, FRAME_LENGTH + EXTRAFRAME_OFFSET, intData,
- offset, nRemaining);
- offset += nRemaining;
-
- System.arraycopy(copies, 0, intData, offset, EXTRAFRAME_OFFSET);
- offset += EXTRAFRAME_OFFSET;
-
- System.arraycopy(seed, HASH_OFFSET, intData, offset,
- EXTRAFRAME_OFFSET);
- }
- for (int i = 0; i < intData.length; i++) {
- oos.writeInt(intData[i]);
- }
-
- oos.writeInt(nextBIndex);
- oos.write(nextBytes, nextBIndex, HASHBYTES_TO_USE - nextBIndex);
- }
-
- private void readObject(ObjectInputStream ois) throws IOException,
- ClassNotFoundException {
-
- seed = new int[HASH_OFFSET + EXTRAFRAME_OFFSET];
- copies = new int[2 * FRAME_LENGTH + EXTRAFRAME_OFFSET];
- nextBytes = new byte[DIGEST_LENGTH];
-
- seedLength = ois.readLong();
- counter = ois.readLong();
- state = ois.readInt();
- seed[BYTES_OFFSET] = ois.readInt();
-
- int nRemaining = (seed[BYTES_OFFSET] + 3) >> 2; // converting bytes in words
-
- if (state != NEXT_BYTES) {
-
- for (int i = 0; i < nRemaining; i++) {
- seed[i] = ois.readInt();
- }
- for (int i = 0; i < EXTRAFRAME_OFFSET; i++) {
- seed[HASH_OFFSET + i] = ois.readInt();
- }
- } else {
- if (seed[BYTES_OFFSET] >= MAX_BYTES) {
-
- // reading next bytes in seed extra frame
- seed[FRAME_LENGTH] = ois.readInt();
- seed[FRAME_LENGTH + 1] = ois.readInt();
- seed[FRAME_LENGTH + 14] = ois.readInt();
- seed[FRAME_LENGTH + 15] = ois.readInt();
- }
- // reading next bytes in seed frame
- for (int i = 0; i < FRAME_LENGTH; i++) {
- seed[i] = ois.readInt();
- }
- // reading remaining seed bytes
- for (int i = 0; i < nRemaining; i++) {
- copies[FRAME_LENGTH + EXTRAFRAME_OFFSET + i] = ois.readInt();
- }
- // reading copy of current hash
- for (int i = 0; i < EXTRAFRAME_OFFSET; i++) {
- copies[i] = ois.readInt();
- }
- // reading current hash
- for (int i = 0; i < EXTRAFRAME_OFFSET; i++) {
- seed[HASH_OFFSET + i] = ois.readInt();
- }
- }
-
- nextBIndex = ois.readInt();
- Streams.readFully(ois, nextBytes, nextBIndex, HASHBYTES_TO_USE - nextBIndex);
- }
-
- private static byte[] getRandomBytes(int byteCount) {
- if (byteCount <= 0) {
- throw new IllegalArgumentException("Too few bytes requested: " + byteCount);
- }
-
- BlockGuard.Policy originalPolicy = BlockGuard.getThreadPolicy();
- try {
- BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY);
- byte[] result = new byte[byteCount];
- Streams.readFully(devURandom, result, 0, byteCount);
- return result;
- } catch (Exception ex) {
- throw new ProviderException("Couldn't read " + byteCount + " random bytes", ex);
- } finally {
- BlockGuard.setThreadPolicy(originalPolicy);
- }
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/security/utils/AlgNameMapper.java b/luni/src/main/java/org/apache/harmony/security/utils/AlgNameMapper.java
index c1d73df..8df02c9 100644
--- a/luni/src/main/java/org/apache/harmony/security/utils/AlgNameMapper.java
+++ b/luni/src/main/java/org/apache/harmony/security/utils/AlgNameMapper.java
@@ -87,14 +87,33 @@
static {
for (String[] element : knownAlgMappings) {
- String algUC = element[1].toUpperCase(Locale.US);
- alg2OidMap.put(algUC, element[0]);
- oid2AlgMap.put(element[0], algUC);
- // map upper case alg name to its original name
- algAliasesMap.put(algUC, element[1]);
+ addMapping(element[0], element[1]);
}
}
+ /**
+ * Adds a mapping to the internal table. Will overwrite any entry already
+ * present. Visible for testing.
+ */
+ public static void addMapping(String oid, String name) {
+ String nameUC = name.toUpperCase(Locale.ROOT);
+ alg2OidMap.put(nameUC, oid);
+ oid2AlgMap.put(oid, nameUC);
+ // map upper case alg name to its original name
+ algAliasesMap.put(nameUC, name);
+ }
+
+ /**
+ * Removes a mapping from the internal table. Visible for testing.
+ */
+ public static void removeMapping(String oid, String name) {
+ String nameUC = name.toUpperCase(Locale.ROOT);
+ alg2OidMap.remove(nameUC);
+ oid2AlgMap.remove(oid);
+ // map upper case alg name to its original name
+ algAliasesMap.remove(nameUC);
+ }
+
// No instances
private AlgNameMapper() {
}
@@ -126,7 +145,7 @@
checkCacheVersion();
// alg2OidMap map contains upper case keys
- String result = alg2OidMap.get(algName.toUpperCase(Locale.US));
+ String result = alg2OidMap.get(algName.toUpperCase(Locale.ROOT));
if (result != null) {
return result;
}
@@ -144,7 +163,7 @@
* Returns algName for OID
*
* @param oid OID to be mapped
- * @return algorithm name
+ * @return algorithm name or {@code null} if not found.
*/
public static String map2AlgName(String oid) {
checkCacheVersion();
@@ -172,7 +191,7 @@
* @return algorithm name
*/
public static String getStandardName(String algName) {
- return algAliasesMap.get(algName.toUpperCase(Locale.US));
+ return algAliasesMap.get(algName.toUpperCase(Locale.ROOT));
}
// Searches given provider for mappings like
@@ -185,11 +204,11 @@
for (String service : serviceName) {
String keyPrfix2find = "Alg.Alias." + service + ".";
for (Entry<Object, Object> me : entrySet) {
- String key = (String)me.getKey();
+ String key = (String) me.getKey();
if (key.startsWith(keyPrfix2find)) {
String alias = key.substring(keyPrfix2find.length());
- String alg = (String)me.getValue();
- String algUC = alg.toUpperCase(Locale.US);
+ String alg = (String) me.getValue();
+ String algUC = alg.toUpperCase(Locale.ROOT);
if (isOID(alias)) {
if (alias.startsWith("OID.")) {
alias = alias.substring(4);
@@ -207,9 +226,9 @@
// map upper case alg name to its original name
algAliasesMap.put(algUC, alg);
}
- // Do not override known standard names
- } else if (!algAliasesMap.containsKey(alias.toUpperCase(Locale.US))) {
- algAliasesMap.put(alias.toUpperCase(Locale.US), alg);
+ // Do not override known standard names
+ } else if (!algAliasesMap.containsKey(alias.toUpperCase(Locale.ROOT))) {
+ algAliasesMap.put(alias.toUpperCase(Locale.ROOT), alg);
}
}
}
diff --git a/luni/src/main/native/AsynchronousCloseMonitor.cpp b/luni/src/main/native/AsynchronousCloseMonitor.cpp
index 31cde00..6c9b2e5 100644
--- a/luni/src/main/native/AsynchronousCloseMonitor.cpp
+++ b/luni/src/main/native/AsynchronousCloseMonitor.cpp
@@ -38,11 +38,7 @@
* The specific signal chosen here is arbitrary, but bionic needs to know so that SIGRTMIN
* starts at a higher value.
*/
-#if defined(__APPLE__)
-static const int BLOCKED_THREAD_SIGNAL = SIGUSR2;
-#else
static const int BLOCKED_THREAD_SIGNAL = __SIGRTMIN + 2;
-#endif
static void blockedThreadSignalHandler(int /*signal*/) {
// Do nothing. We only sent this signal for its side-effect of interrupting syscalls.
diff --git a/luni/src/main/native/NetworkUtilities.cpp b/luni/src/main/native/NetworkUtilities.cpp
index 7215306..f2d0f8a 100644
--- a/luni/src/main/native/NetworkUtilities.cpp
+++ b/luni/src/main/native/NetworkUtilities.cpp
@@ -61,10 +61,6 @@
addressLength = 16;
sin_port = ntohs(sin6.sin6_port);
scope_id = sin6.sin6_scope_id;
- } else if (ss.ss_family == AF_UNIX) {
- const sockaddr_un& sun = reinterpret_cast<const sockaddr_un&>(ss);
- rawAddress = &sun.sun_path;
- addressLength = strlen(sun.sun_path);
} else {
// We can't throw SocketException. We aren't meant to see bad addresses, so seeing one
// really does imply an internal error.
@@ -83,14 +79,6 @@
env->SetByteArrayRegion(byteArray.get(), 0, addressLength,
reinterpret_cast<const jbyte*>(rawAddress));
- if (ss.ss_family == AF_UNIX) {
- // Note that we get here for AF_UNIX sockets on accept(2). The unix(7) man page claims
- // that the peer's sun_path will contain the path, but in practice it doesn't, and the
- // peer length is returned as 2 (meaning only the sun_family field was set).
- static jmethodID ctor = env->GetMethodID(JniConstants::inetUnixAddressClass, "<init>", "([B)V");
- return env->NewObject(JniConstants::inetUnixAddressClass, ctor, byteArray.get());
- }
-
static jmethodID getByAddressMethod = env->GetStaticMethodID(JniConstants::inetAddressClass,
"getByAddress", "(Ljava/lang/String;[BI)Ljava/net/InetAddress;");
if (getByAddressMethod == NULL) {
@@ -118,7 +106,7 @@
}
// Check this is an address family we support.
- if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6 && ss.ss_family != AF_UNIX) {
+ if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6) {
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
"inetAddressToSockaddr bad family: %i", ss.ss_family);
return false;
@@ -132,25 +120,6 @@
return false;
}
- // Handle the AF_UNIX special case.
- if (ss.ss_family == AF_UNIX) {
- sockaddr_un& sun = reinterpret_cast<sockaddr_un&>(ss);
-
- size_t path_length = env->GetArrayLength(addressBytes.get());
- if (path_length >= sizeof(sun.sun_path)) {
- jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
- "inetAddressToSockaddr path too long for AF_UNIX: %i", path_length);
- return false;
- }
-
- // Copy the bytes...
- jbyte* dst = reinterpret_cast<jbyte*>(&sun.sun_path);
- memset(dst, 0, sizeof(sun.sun_path));
- env->GetByteArrayRegion(addressBytes.get(), 0, path_length, dst);
- sa_len = sizeof(sun.sun_path);
- return true;
- }
-
// TODO: bionic's getnameinfo(3) seems to want its length parameter to be exactly
// sizeof(sockaddr_in) for an IPv4 address and sizeof (sockaddr_in6) for an
// IPv6 address. Fix getnameinfo so it accepts sizeof(sockaddr_storage), and
diff --git a/luni/src/main/native/NetworkUtilities.h b/luni/src/main/native/NetworkUtilities.h
index 6b720d4..db1ad1f 100644
--- a/luni/src/main/native/NetworkUtilities.h
+++ b/luni/src/main/native/NetworkUtilities.h
@@ -17,25 +17,24 @@
#include "jni.h"
#include <sys/socket.h>
-// Convert from sockaddr_storage to Inet4Address (AF_INET), Inet6Address (AF_INET6), or
-// InetUnixAddress (AF_UNIX). If 'port' is non-NULL and the address family includes a notion
+// Convert from sockaddr_storage to Inet4Address (AF_INET) or Inet6Address (AF_INET6).
+// If 'port' is non-NULL and the address family includes a notion
// of port number, *port will be set to the port number.
jobject sockaddrToInetAddress(JNIEnv* env, const sockaddr_storage& ss, int* port);
-// Convert from InetAddress to sockaddr_storage. An InetUnixAddress will be converted to
-// an AF_UNIX sockaddr_un. An Inet6Address will be converted to an AF_INET6 sockaddr_in6.
-// An Inet4Address will be converted to an IPv4-mapped AF_INET6 sockaddr_in6. This is what
-// you want if you're about to perform an operation on a socket, since all our sockets
-// are AF_INET6.
+// Convert from InetAddress to sockaddr_storage. An Inet6Address will be converted to an
+// AF_INET6 sockaddr_in6. An Inet4Address will be converted to an IPv4-mapped AF_INET6
+// sockaddr_in6. This is what you want if you're about to perform an operation on a socket,
+// since all our sockets are AF_INET6.
bool inetAddressToSockaddr(JNIEnv* env, jobject inetAddress, int port,
sockaddr_storage& ss, socklen_t& sa_len);
-// Convert from InetAddress to sockaddr_storage. An InetUnixAddress will be converted to
-// an AF_UNIX sockaddr_un. An Inet6Address will be converted to an AF_INET6 sockaddr_in6.
-// An Inet4Address will be converted to a sockaddr_in. This is probably only useful for
-// getnameinfo(2), where we'll be presenting the result to the user and the user may actually
-// care whether the original address was pure IPv4 or an IPv4-mapped IPv6 address, and
-// for the MCAST_JOIN_GROUP, MCAST_LEAVE_GROUP, and other multicast socket options.
+// Convert from InetAddress to sockaddr_storage. An Inet6Address will be converted to an
+// AF_INET6 sockaddr_in6. An Inet4Address will be converted to a sockaddr_in. This is probably
+// only useful for getnameinfo(2), where we'll be presenting the result to the user and the
+// user may actually care whether the original address was pure IPv4 or an IPv4-mapped IPv6
+// address, and for the MCAST_JOIN_GROUP, MCAST_LEAVE_GROUP, and other multicast socket
+// options.
bool inetAddressToSockaddrVerbatim(JNIEnv* env, jobject inetAddress, int port,
sockaddr_storage& ss, socklen_t& sa_len);
diff --git a/luni/src/main/native/Portability.h b/luni/src/main/native/Portability.h
index 5900cb0..4df3353 100644
--- a/luni/src/main/native/Portability.h
+++ b/luni/src/main/native/Portability.h
@@ -17,64 +17,10 @@
#ifndef PORTABILITY_H_included
#define PORTABILITY_H_included
-#if defined(__APPLE__)
-
-// Mac OS.
-#include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_MAX_ALLOWED
-
-#include <libkern/OSByteOrder.h>
-#define bswap_16 OSSwapInt16
-#define bswap_32 OSSwapInt32
-#define bswap_64 OSSwapInt64
-
-#include <crt_externs.h>
-#define environ (*_NSGetEnviron())
-
-// Mac OS has a 64-bit off_t and no 32-bit compatibility cruft.
-#define flock64 flock
-#define ftruncate64 ftruncate
-#define isnanf __inline_isnanf
-#define lseek64 lseek
-#define pread64 pread
-#define pwrite64 pwrite
-
-// TODO: Darwin appears to have an fdatasync syscall.
-static inline int fdatasync(int fd) { return fsync(fd); }
-
-// For Linux-compatible sendfile(3).
-#include <sys/socket.h>
-#include <sys/types.h>
-static inline ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) {
- off_t in_out_count = count;
- int result = sendfile(in_fd, out_fd, *offset, &in_out_count, NULL, 0);
- if (result == -1) {
- return -1;
- }
- return in_out_count;
-}
-
-// For mincore(3).
-#define _DARWIN_C_SOURCE
-#include <sys/mman.h>
-#undef _DARWIN_C_SOURCE
-static inline int mincore(void* addr, size_t length, unsigned char* vec) {
- return mincore(addr, length, reinterpret_cast<char*>(vec));
-}
-
-// For statfs(3).
-#include <sys/param.h>
-#include <sys/mount.h>
-
-#else
-
-// Bionic or glibc.
-
#include <byteswap.h>
#include <sys/sendfile.h>
#include <sys/statvfs.h>
-#endif
-
#include <netdb.h>
#if defined(__BIONIC__)
extern "C" int android_getaddrinfofornet(const char*, const char*, const struct addrinfo*, unsigned, unsigned, struct addrinfo**);
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 787a149..c32e675 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -47,7 +47,6 @@
REGISTER(register_java_lang_StringToReal);
REGISTER(register_java_lang_System);
REGISTER(register_java_math_NativeBN);
- REGISTER(register_java_text_Bidi);
REGISTER(register_java_util_jar_StrictJarFile);
REGISTER(register_java_util_regex_Matcher);
REGISTER(register_java_util_regex_Pattern);
@@ -55,16 +54,11 @@
REGISTER(register_java_util_zip_CRC32);
REGISTER(register_java_util_zip_Deflater);
REGISTER(register_java_util_zip_Inflater);
- REGISTER(register_libcore_icu_AlphabeticIndex);
REGISTER(register_libcore_icu_ICU);
REGISTER(register_libcore_icu_NativeCollation);
REGISTER(register_libcore_icu_NativeConverter);
REGISTER(register_libcore_icu_NativeDecimalFormat);
- REGISTER(register_libcore_icu_NativeIDN);
- REGISTER(register_libcore_icu_NativeNormalizer);
- REGISTER(register_libcore_icu_NativePluralRules);
REGISTER(register_libcore_icu_TimeZoneNames);
- REGISTER(register_libcore_icu_Transliterator);
REGISTER(register_libcore_io_AsynchronousCloseMonitor);
REGISTER(register_libcore_io_Memory);
REGISTER(register_libcore_io_Posix);
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index a44d176..074bbef 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -30,22 +30,20 @@
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
-#ifndef __APPLE__
#include <sys/prctl.h>
-#endif
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/un.h>
#include <sys/wait.h>
+#include <sys/xattr.h>
#include <unistd.h>
#include <net/if_arp.h>
#include <linux/if_ether.h>
// After the others because these are not necessarily self-contained in glibc.
-#ifndef __APPLE__
#include <linux/if_addr.h>
#include <linux/rtnetlink.h>
-#endif
#include <net/if.h> // After <sys/socket.h> to work around a Mac header file bug.
@@ -210,6 +208,7 @@
initConstant(env, c, "ETIME", ETIME);
initConstant(env, c, "ETIMEDOUT", ETIMEDOUT);
initConstant(env, c, "ETXTBSY", ETXTBSY);
+ initConstant(env, c, "EUSERS", EUSERS);
#if EWOULDBLOCK != EAGAIN
#error EWOULDBLOCK != EAGAIN
#endif
@@ -383,6 +382,7 @@
initConstant(env, c, "O_RDONLY", O_RDONLY);
initConstant(env, c, "O_RDWR", O_RDWR);
initConstant(env, c, "O_SYNC", O_SYNC);
+ initConstant(env, c, "O_DSYNC", O_DSYNC);
initConstant(env, c, "O_TRUNC", O_TRUNC);
initConstant(env, c, "O_WRONLY", O_WRONLY);
initConstant(env, c, "POLLERR", POLLERR);
@@ -413,7 +413,6 @@
// members. The best we can do (barring UAPI / kernel version checks) is
// to hope they exist on all host linuxes we're building on. These
// constants have been around since 2.6.35 at least, so we should be ok.
-#if !defined(__APPLE__)
initConstant(env, c, "RT_SCOPE_HOST", RT_SCOPE_HOST);
initConstant(env, c, "RT_SCOPE_LINK", RT_SCOPE_LINK);
initConstant(env, c, "RT_SCOPE_NOWHERE", RT_SCOPE_NOWHERE);
@@ -432,7 +431,6 @@
initConstant(env, c, "RTMGRP_NEIGH", RTMGRP_NEIGH);
initConstant(env, c, "RTMGRP_NOTIFY", RTMGRP_NOTIFY);
initConstant(env, c, "RTMGRP_TC", RTMGRP_TC);
-#endif
initConstant(env, c, "SEEK_CUR", SEEK_CUR);
initConstant(env, c, "SEEK_END", SEEK_END);
initConstant(env, c, "SEEK_SET", SEEK_SET);
@@ -549,6 +547,9 @@
initConstant(env, c, "S_IXOTH", S_IXOTH);
initConstant(env, c, "S_IXUSR", S_IXUSR);
initConstant(env, c, "TCP_NODELAY", TCP_NODELAY);
+ initConstant(env, c, "TIOCOUTQ", TIOCOUTQ);
+ // UNIX_PATH_MAX is mentioned in some versions of unix(7), but not actually declared.
+ initConstant(env, c, "UNIX_PATH_MAX", sizeof(sockaddr_un::sun_path));
initConstant(env, c, "WCONTINUED", WCONTINUED);
initConstant(env, c, "WEXITED", WEXITED);
initConstant(env, c, "WNOHANG", WNOHANG);
@@ -556,6 +557,8 @@
initConstant(env, c, "WSTOPPED", WSTOPPED);
initConstant(env, c, "WUNTRACED", WUNTRACED);
initConstant(env, c, "W_OK", W_OK);
+ initConstant(env, c, "XATTR_CREATE", XATTR_CREATE);
+ initConstant(env, c, "XATTR_REPLACE", XATTR_REPLACE);
initConstant(env, c, "X_OK", X_OK);
initConstant(env, c, "_SC_2_CHAR_TERM", _SC_2_CHAR_TERM);
initConstant(env, c, "_SC_2_C_BIND", _SC_2_C_BIND);
diff --git a/luni/src/main/native/cbigint.cpp b/luni/src/main/native/cbigint.cpp
index 6943ca2..c202ed7 100644
--- a/luni/src/main/native/cbigint.cpp
+++ b/luni/src/main/native/cbigint.cpp
@@ -18,31 +18,9 @@
#include <string.h>
#include "cbigint.h"
-#if defined(__linux__) || defined(__APPLE__)
-#define USE_LL
-#endif
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define at(i) (i)
-#else
-#define at(i) ((i)^1)
-/* the sequence for halfAt is -1, 2, 1, 4, 3, 6, 5, 8... */
-/* and it should correspond to 0, 1, 2, 3, 4, 5, 6, 7... */
-#define halfAt(i) (-((-(i)) ^ 1))
-#endif
-
#define HIGH_IN_U64(u64) ((u64) >> 32)
-#if defined(USE_LL)
#define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFLL)
-#else
-#if defined(USE_L)
-#define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFL)
-#else
-#define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFF)
-#endif /* USE_L */
-#endif /* USE_LL */
-#if defined(USE_LL)
#define TEN_E1 (0xALL)
#define TEN_E2 (0x64LL)
#define TEN_E3 (0x3E8LL)
@@ -53,54 +31,15 @@
#define TEN_E8 (0x5F5E100LL)
#define TEN_E9 (0x3B9ACA00LL)
#define TEN_E19 (0x8AC7230489E80000LL)
-#else
-#if defined(USE_L)
-#define TEN_E1 (0xAL)
-#define TEN_E2 (0x64L)
-#define TEN_E3 (0x3E8L)
-#define TEN_E4 (0x2710L)
-#define TEN_E5 (0x186A0L)
-#define TEN_E6 (0xF4240L)
-#define TEN_E7 (0x989680L)
-#define TEN_E8 (0x5F5E100L)
-#define TEN_E9 (0x3B9ACA00L)
-#define TEN_E19 (0x8AC7230489E80000L)
-#else
-#define TEN_E1 (0xA)
-#define TEN_E2 (0x64)
-#define TEN_E3 (0x3E8)
-#define TEN_E4 (0x2710)
-#define TEN_E5 (0x186A0)
-#define TEN_E6 (0xF4240)
-#define TEN_E7 (0x989680)
-#define TEN_E8 (0x5F5E100)
-#define TEN_E9 (0x3B9ACA00)
-#define TEN_E19 (0x8AC7230489E80000)
-#endif /* USE_L */
-#endif /* USE_LL */
#define TIMES_TEN(x) (((x) << 3) + ((x) << 1))
#define bitSection(x, mask, shift) (((x) & (mask)) >> (shift))
#define CREATE_DOUBLE_BITS(normalizedM, e) (((normalizedM) & MANTISSA_MASK) | ((static_cast<uint64_t>((e) + E_OFFSET)) << 52))
-#if defined(USE_LL)
#define MANTISSA_MASK (0x000FFFFFFFFFFFFFLL)
#define EXPONENT_MASK (0x7FF0000000000000LL)
#define NORMAL_MASK (0x0010000000000000LL)
#define SIGN_MASK (0x8000000000000000LL)
-#else
-#if defined(USE_L)
-#define MANTISSA_MASK (0x000FFFFFFFFFFFFFL)
-#define EXPONENT_MASK (0x7FF0000000000000L)
-#define NORMAL_MASK (0x0010000000000000L)
-#define SIGN_MASK (0x8000000000000000L)
-#else
-#define MANTISSA_MASK (0x000FFFFFFFFFFFFF)
-#define EXPONENT_MASK (0x7FF0000000000000)
-#define NORMAL_MASK (0x0010000000000000)
-#define SIGN_MASK (0x8000000000000000)
-#endif /* USE_L */
-#endif /* USE_LL */
#define E_OFFSET (1075)
@@ -229,53 +168,28 @@
do
{
product =
- HIGH_IN_U64 (product) + result[at (resultIndex)] +
+ HIGH_IN_U64 (product) + result[resultIndex] +
arg2 * LOW_U32_FROM_PTR (arg1 + index);
- result[at (resultIndex)] = LOW_U32_FROM_VAR (product);
+ result[resultIndex] = LOW_U32_FROM_VAR (product);
++resultIndex;
product =
- HIGH_IN_U64 (product) + result[at (resultIndex)] +
+ HIGH_IN_U64 (product) + result[resultIndex] +
arg2 * HIGH_U32_FROM_PTR (arg1 + index);
- result[at (resultIndex)] = LOW_U32_FROM_VAR (product);
+ result[resultIndex] = LOW_U32_FROM_VAR (product);
++resultIndex;
}
while (++index < length);
- result[at (resultIndex)] += HIGH_U32_FROM_VAR (product);
- if (result[at (resultIndex)] < HIGH_U32_FROM_VAR (product))
+ result[resultIndex] += HIGH_U32_FROM_VAR (product);
+ if (result[resultIndex] < HIGH_U32_FROM_VAR (product))
{
/* must be careful with ++ operator and macro expansion */
++resultIndex;
- while (++result[at (resultIndex)] == 0)
+ while (++result[resultIndex] == 0)
++resultIndex;
}
}
-#if __BYTE_ORDER != __LITTLE_ENDIAN
-void simpleMultiplyAddHighPrecisionBigEndianFix(uint64_t* arg1, int32_t length, uint64_t arg2, uint32_t* result) {
- /* Assumes result can hold the product and arg2 only holds 32 bits of information */
- int32_t index = 0;
- int32_t resultIndex = 0;
- uint64_t product = 0;
-
- do {
- product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * LOW_U32_FROM_PTR(arg1 + index);
- result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product);
- ++resultIndex;
- product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * HIGH_U32_FROM_PTR(arg1 + index);
- result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product);
- ++resultIndex;
- } while (++index < length);
-
- result[halfAt(resultIndex)] += HIGH_U32_FROM_VAR(product);
- if (result[halfAt(resultIndex)] < HIGH_U32_FROM_VAR(product)) {
- /* must be careful with ++ operator and macro expansion */
- ++resultIndex;
- while (++result[halfAt(resultIndex)] == 0) ++resultIndex;
- }
-}
-#endif
-
void
multiplyHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2,
uint64_t * result, int32_t length)
@@ -304,11 +218,7 @@
{
simpleMultiplyAddHighPrecision (arg1, length1, LOW_IN_U64 (arg2[count]),
resultIn32 + (++index));
-#if __BYTE_ORDER == __LITTLE_ENDIAN
simpleMultiplyAddHighPrecision(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index));
-#else
- simpleMultiplyAddHighPrecisionBigEndianFix(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index));
-#endif
}
}
@@ -374,7 +284,6 @@
if (*y == 0)
return 0;
-#if defined(USE_LL)
if (*y & 0xFFFFFFFF00000000LL)
{
x = HIGH_U32_FROM_PTR (y);
@@ -385,31 +294,6 @@
x = LOW_U32_FROM_PTR (y);
result = 0;
}
-#else
-#if defined(USE_L)
- if (*y & 0xFFFFFFFF00000000L)
- {
- x = HIGH_U32_FROM_PTR (y);
- result = 32;
- }
- else
- {
- x = LOW_U32_FROM_PTR (y);
- result = 0;
- }
-#else
- if (*y & 0xFFFFFFFF00000000)
- {
- x = HIGH_U32_FROM_PTR (y);
- result = 32;
- }
- else
- {
- x = LOW_U32_FROM_PTR (y);
- result = 0;
- }
-#endif /* USE_L */
-#endif /* USE_LL */
if (x & 0xFFFF0000)
{
@@ -445,7 +329,6 @@
if (*y == 0)
return 0;
-#if defined(USE_LL)
if (*y & 0x00000000FFFFFFFFLL)
{
x = LOW_U32_FROM_PTR (y);
@@ -456,31 +339,6 @@
x = HIGH_U32_FROM_PTR (y);
result = 32;
}
-#else
-#if defined(USE_L)
- if (*y & 0x00000000FFFFFFFFL)
- {
- x = LOW_U32_FROM_PTR (y);
- result = 0;
- }
- else
- {
- x = HIGH_U32_FROM_PTR (y);
- result = 32;
- }
-#else
- if (*y & 0x00000000FFFFFFFF)
- {
- x = LOW_U32_FROM_PTR (y);
- result = 0;
- }
- else
- {
- x = HIGH_U32_FROM_PTR (y);
- result = 32;
- }
-#endif /* USE_L */
-#endif /* USE_LL */
if (!(x & 0xFFFF))
{
diff --git a/luni/src/main/native/java_lang_ProcessManager.cpp b/luni/src/main/native/java_lang_ProcessManager.cpp
index 3a97ac6..efa5e77 100644
--- a/luni/src/main/native/java_lang_ProcessManager.cpp
+++ b/luni/src/main/native/java_lang_ProcessManager.cpp
@@ -38,11 +38,6 @@
static void CloseNonStandardFds(int status_pipe_fd) {
// On Cygwin, Linux, and Solaris, the best way to close iterates over "/proc/self/fd/".
const char* fd_path = "/proc/self/fd";
-#if defined(__APPLE__)
- // On Mac OS, there's "/dev/fd/" which Linux seems to link to "/proc/self/fd/",
- // but which on Solaris appears to be something quite different.
- fd_path = "/dev/fd";
-#endif
// Keep track of the system properties fd so we don't close it.
int properties_fd = -1;
diff --git a/luni/src/main/native/java_lang_System.cpp b/luni/src/main/native/java_lang_System.cpp
index 306adab..1ba230a 100644
--- a/luni/src/main/native/java_lang_System.cpp
+++ b/luni/src/main/native/java_lang_System.cpp
@@ -34,7 +34,7 @@
#include <time.h>
#include <unistd.h>
-#if defined(HAVE_ANDROID_OS)
+#if defined(__ANDROID__)
extern "C" void android_get_LD_LIBRARY_PATH(char*, size_t);
#endif
@@ -91,7 +91,7 @@
#endif
const char* library_path = getenv("LD_LIBRARY_PATH");
-#if defined(HAVE_ANDROID_OS)
+#if defined(__ANDROID__)
if (library_path == NULL) {
android_get_LD_LIBRARY_PATH(path, sizeof(path));
library_path = path;
@@ -113,15 +113,9 @@
}
static jlong System_nanoTime(JNIEnv*, jclass) {
-#if defined(__linux__)
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return now.tv_sec * 1000000000LL + now.tv_nsec;
-#else // __APPLE__
- timeval now;
- gettimeofday(&now, NULL);
- return static_cast<jlong>(now.tv_sec) * 1000000000LL + now.tv_usec * 1000LL;
-#endif
}
static JNINativeMethod gMethods[] = {
diff --git a/luni/src/main/native/java_text_Bidi.cpp b/luni/src/main/native/java_text_Bidi.cpp
deleted file mode 100644
index 6a3e751..0000000
--- a/luni/src/main/native/java_text_Bidi.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Bidi"
-
-#include "IcuUtilities.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "ScopedPrimitiveArray.h"
-#include "unicode/ubidi.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <memory>
-
-struct BiDiData {
- BiDiData(UBiDi* biDi) : mBiDi(biDi) {
- }
-
- ~BiDiData() {
- ubidi_close(mBiDi);
- }
-
- UBiDiLevel* embeddingLevels() {
- return reinterpret_cast<UBiDiLevel*>(&mEmbeddingLevels[0]);
- }
-
- void setEmbeddingLevels(jbyte* newEmbeddingLevels) {
- mEmbeddingLevels.reset(newEmbeddingLevels);
- }
-
- UBiDi* uBiDi() {
- return mBiDi;
- }
-
-private:
- UBiDi* mBiDi;
- std::unique_ptr<jbyte[]> mEmbeddingLevels;
-
- // Disallow copy and assignment.
- BiDiData(const BiDiData&);
- void operator=(const BiDiData&);
-};
-
-static BiDiData* biDiData(jlong ptr) {
- return reinterpret_cast<BiDiData*>(static_cast<uintptr_t>(ptr));
-}
-
-static UBiDi* uBiDi(jlong ptr) {
- return reinterpret_cast<BiDiData*>(static_cast<uintptr_t>(ptr))->uBiDi();
-}
-
-static jlong Bidi_ubidi_open(JNIEnv*, jclass) {
- return reinterpret_cast<uintptr_t>(new BiDiData(ubidi_open()));
-}
-
-static void Bidi_ubidi_close(JNIEnv*, jclass, jlong ptr) {
- delete biDiData(ptr);
-}
-
-static void Bidi_ubidi_setPara(JNIEnv* env, jclass, jlong ptr, jcharArray text, jint length, jint paraLevel, jbyteArray newEmbeddingLevels) {
- BiDiData* data = biDiData(ptr);
- // Copy the new embedding levels from the Java heap to the native heap.
- if (newEmbeddingLevels != NULL) {
- jbyte* dst;
- data->setEmbeddingLevels(dst = new jbyte[length]);
- env->GetByteArrayRegion(newEmbeddingLevels, 0, length, dst);
- } else {
- data->setEmbeddingLevels(NULL);
- }
- ScopedCharArrayRO chars(env, text);
- if (chars.get() == NULL) {
- return;
- }
- UErrorCode err = U_ZERO_ERROR;
- ubidi_setPara(data->uBiDi(), chars.get(), length, paraLevel, data->embeddingLevels(), &err);
- maybeThrowIcuException(env, "ubidi_setPara", err);
-}
-
-static jlong Bidi_ubidi_setLine(JNIEnv* env, jclass, jlong ptr, jint start, jint limit) {
- UErrorCode status = U_ZERO_ERROR;
- UBiDi* sized = ubidi_openSized(limit - start, 0, &status);
- if (maybeThrowIcuException(env, "ubidi_openSized", status)) {
- return 0;
- }
- std::unique_ptr<BiDiData> lineData(new BiDiData(sized));
- ubidi_setLine(uBiDi(ptr), start, limit, lineData->uBiDi(), &status);
- maybeThrowIcuException(env, "ubidi_setLine", status);
- return reinterpret_cast<uintptr_t>(lineData.release());
-}
-
-static jint Bidi_ubidi_getDirection(JNIEnv*, jclass, jlong ptr) {
- return ubidi_getDirection(uBiDi(ptr));
-}
-
-static jint Bidi_ubidi_getLength(JNIEnv*, jclass, jlong ptr) {
- return ubidi_getLength(uBiDi(ptr));
-}
-
-static jbyte Bidi_ubidi_getParaLevel(JNIEnv*, jclass, jlong ptr) {
- return ubidi_getParaLevel(uBiDi(ptr));
-}
-
-static jbyteArray Bidi_ubidi_getLevels(JNIEnv* env, jclass, jlong ptr) {
- UErrorCode status = U_ZERO_ERROR;
- const UBiDiLevel* levels = ubidi_getLevels(uBiDi(ptr), &status);
- if (maybeThrowIcuException(env, "ubidi_getLevels", status)) {
- return NULL;
- }
- int len = ubidi_getLength(uBiDi(ptr));
- jbyteArray result = env->NewByteArray(len);
- env->SetByteArrayRegion(result, 0, len, reinterpret_cast<const jbyte*>(levels));
- return result;
-}
-
-static jint Bidi_ubidi_countRuns(JNIEnv* env, jclass, jlong ptr) {
- UErrorCode status = U_ZERO_ERROR;
- int count = ubidi_countRuns(uBiDi(ptr), &status);
- maybeThrowIcuException(env, "ubidi_countRuns", status);
- return count;
-}
-
-/**
- * TODO: if we care about performance, we might just want to use an int[] instead of a Run[].
- */
-static jobjectArray Bidi_ubidi_getRuns(JNIEnv* env, jclass, jlong ptr) {
- UBiDi* ubidi = uBiDi(ptr);
- UErrorCode status = U_ZERO_ERROR;
- int runCount = ubidi_countRuns(ubidi, &status);
- if (maybeThrowIcuException(env, "ubidi_countRuns", status)) {
- return NULL;
- }
- static jmethodID bidiRunConstructor =
- env->GetMethodID(JniConstants::bidiRunClass, "<init>", "(III)V");
- jobjectArray runs = env->NewObjectArray(runCount, JniConstants::bidiRunClass, NULL);
- UBiDiLevel level = 0;
- int start = 0;
- int limit = 0;
- for (int i = 0; i < runCount; ++i) {
- ubidi_getLogicalRun(ubidi, start, &limit, &level);
- jobject run = env->NewObject(JniConstants::bidiRunClass, bidiRunConstructor, start, limit, level);
- env->SetObjectArrayElement(runs, i, run);
- start = limit;
- }
- return runs;
-}
-
-static jintArray Bidi_ubidi_reorderVisual(JNIEnv* env, jclass, jbyteArray javaLevels, jint length) {
- ScopedByteArrayRO levelBytes(env, javaLevels);
- if (levelBytes.get() == NULL) {
- return NULL;
- }
-
- const UBiDiLevel* levels = reinterpret_cast<const UBiDiLevel*>(levelBytes.get());
-
- std::unique_ptr<int[]> indexMap(new int[length]);
- ubidi_reorderVisual(levels, length, &indexMap[0]);
-
- jintArray result = env->NewIntArray(length);
- env->SetIntArrayRegion(result, 0, length, &indexMap[0]);
- return result;
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(Bidi, ubidi_close, "(J)V"),
- NATIVE_METHOD(Bidi, ubidi_countRuns, "(J)I"),
- NATIVE_METHOD(Bidi, ubidi_getDirection, "(J)I"),
- NATIVE_METHOD(Bidi, ubidi_getLength, "(J)I"),
- NATIVE_METHOD(Bidi, ubidi_getLevels, "(J)[B"),
- NATIVE_METHOD(Bidi, ubidi_getParaLevel, "(J)B"),
- NATIVE_METHOD(Bidi, ubidi_getRuns, "(J)[Ljava/text/Bidi$Run;"),
- NATIVE_METHOD(Bidi, ubidi_open, "()J"),
- NATIVE_METHOD(Bidi, ubidi_reorderVisual, "([BI)[I"),
- NATIVE_METHOD(Bidi, ubidi_setLine, "(JII)J"),
- NATIVE_METHOD(Bidi, ubidi_setPara, "(J[CII[B)V"),
-};
-void register_java_text_Bidi(JNIEnv* env) {
- jniRegisterNativeMethods(env, "java/text/Bidi", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/java_util_jar_StrictJarFile.cpp b/luni/src/main/native/java_util_jar_StrictJarFile.cpp
index 82547bd..13a4db38 100644
--- a/luni/src/main/native/java_util_jar_StrictJarFile.cpp
+++ b/luni/src/main/native/java_util_jar_StrictJarFile.cpp
@@ -97,11 +97,11 @@
int32_t error = 0;
if (prefixChars.size() == 0) {
error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
- handle->CookieAddress(), NULL);
+ handle->CookieAddress(), NULL, NULL);
} else {
- ZipEntryName entry_name(prefixChars.c_str());
+ ZipString entry_name(prefixChars.c_str());
error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
- handle->CookieAddress(), &entry_name);
+ handle->CookieAddress(), &entry_name, NULL);
}
if (error) {
@@ -114,7 +114,7 @@
static jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterationHandle) {
ZipEntry data;
- ZipEntryName entryName;
+ ZipString entryName;
IterationHandle* handle = reinterpret_cast<IterationHandle*>(iterationHandle);
const int32_t error = Next(*handle->CookieAddress(), &data, &entryName);
@@ -140,7 +140,7 @@
ZipEntry data;
const int32_t error = FindEntry(reinterpret_cast<ZipArchiveHandle>(nativeHandle),
- ZipEntryName(entryNameChars.c_str()), &data);
+ ZipString(entryNameChars.c_str()), &data);
if (error) {
return NULL;
}
diff --git a/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp b/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp
deleted file mode 100644
index acc247b..0000000
--- a/luni/src/main/native/libcore_icu_AlphabeticIndex.cpp
+++ /dev/null
@@ -1,206 +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.
- */
-
-#define LOG_TAG "AlphabeticIndex"
-
-#include "IcuUtilities.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "ScopedIcuLocale.h"
-#include "ScopedJavaUnicodeString.h"
-#include "unicode/alphaindex.h"
-#include "unicode/uniset.h"
-
-static icu::AlphabeticIndex* fromPeer(jlong peer) {
- return reinterpret_cast<icu::AlphabeticIndex*>(static_cast<uintptr_t>(peer));
-}
-
-static jlong AlphabeticIndex_create(JNIEnv* env, jclass, jstring javaLocaleName) {
- UErrorCode status = U_ZERO_ERROR;
- ScopedIcuLocale icuLocale(env, javaLocaleName);
- if (!icuLocale.valid()) {
- return 0;
- }
- icu::AlphabeticIndex* ai = new icu::AlphabeticIndex(icuLocale.locale(), status);
- if (maybeThrowIcuException(env, "AlphabeticIndex", status)) {
- return 0;
- }
- return reinterpret_cast<uintptr_t>(ai);
-}
-
-static void AlphabeticIndex_destroy(JNIEnv*, jclass, jlong peer) {
- delete fromPeer(peer);
-}
-
-static jint AlphabeticIndex_getMaxLabelCount(JNIEnv*, jclass, jlong peer) {
- icu::AlphabeticIndex* ai = fromPeer(peer);
- return ai->getMaxLabelCount();
-}
-
-static void AlphabeticIndex_setMaxLabelCount(JNIEnv* env, jclass, jlong peer, jint count) {
- icu::AlphabeticIndex* ai = fromPeer(peer);
- UErrorCode status = U_ZERO_ERROR;
- ai->setMaxLabelCount(count, status);
- maybeThrowIcuException(env, "AlphabeticIndex::setMaxLabelCount", status);
-}
-
-static void AlphabeticIndex_addLabels(JNIEnv* env, jclass, jlong peer, jstring javaLocaleName) {
- icu::AlphabeticIndex* ai = fromPeer(peer);
- ScopedIcuLocale icuLocale(env, javaLocaleName);
- if (!icuLocale.valid()) {
- return;
- }
- UErrorCode status = U_ZERO_ERROR;
- ai->addLabels(icuLocale.locale(), status);
- maybeThrowIcuException(env, "AlphabeticIndex::addLabels", status);
-}
-
-static void AlphabeticIndex_addLabelRange(JNIEnv* env, jclass, jlong peer,
- jint codePointStart, jint codePointEnd) {
- icu::AlphabeticIndex* ai = fromPeer(peer);
- UErrorCode status = U_ZERO_ERROR;
- ai->addLabels(icu::UnicodeSet(codePointStart, codePointEnd), status);
- maybeThrowIcuException(env, "AlphabeticIndex::addLabels", status);
-}
-
-static jint AlphabeticIndex_getBucketCount(JNIEnv* env, jclass, jlong peer) {
- icu::AlphabeticIndex* ai = fromPeer(peer);
- UErrorCode status = U_ZERO_ERROR;
- jint result = ai->getBucketCount(status);
- if (maybeThrowIcuException(env, "AlphabeticIndex::getBucketCount", status)) {
- return -1;
- }
- return result;
-}
-
-static jint AlphabeticIndex_getBucketIndex(JNIEnv* env, jclass, jlong peer, jstring javaString) {
- icu::AlphabeticIndex* ai = fromPeer(peer);
- ScopedJavaUnicodeString string(env, javaString);
- if (!string.valid()) {
- return -1;
- }
- UErrorCode status = U_ZERO_ERROR;
- jint result = ai->getBucketIndex(string.unicodeString(), status);
- if (maybeThrowIcuException(env, "AlphabeticIndex::getBucketIndex", status)) {
- return -1;
- }
- return result;
-}
-
-static jstring AlphabeticIndex_getBucketLabel(JNIEnv* env, jclass, jlong peer, jint index) {
- if (index < 0) {
- jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Invalid index: %d", index);
- return NULL;
- }
-
- // Iterate to the nth bucket.
- icu::AlphabeticIndex* ai = fromPeer(peer);
- UErrorCode status = U_ZERO_ERROR;
- ai->resetBucketIterator(status);
- if (maybeThrowIcuException(env, "AlphabeticIndex::resetBucketIterator", status)) {
- return NULL;
- }
- for (jint i = 0; i <= index; ++i) {
- if (!ai->nextBucket(status)) {
- jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Invalid index: %d", index);
- return NULL;
- }
- if (maybeThrowIcuException(env, "AlphabeticIndex::nextBucket", status)) {
- return NULL;
- }
- }
-
- // Return "" for the underflow/inflow/overflow buckets.
- if (ai->getBucketLabelType() != U_ALPHAINDEX_NORMAL) {
- return env->NewStringUTF("");
- }
-
- const icu::UnicodeString& label(ai->getBucketLabel());
- return env->NewString(label.getBuffer(), label.length());
-}
-
-static jlong AlphabeticIndex_buildImmutableIndex(JNIEnv* env, jclass, jlong peer) {
- icu::AlphabeticIndex* ai = fromPeer(peer);
- UErrorCode status = U_ZERO_ERROR;
- icu::AlphabeticIndex::ImmutableIndex* ii = ai->buildImmutableIndex(status);
- if (maybeThrowIcuException(env, "AlphabeticIndex::buildImmutableIndex", status)) {
- return 0;
- }
- return reinterpret_cast<uintptr_t>(ii);
-}
-
-static icu::AlphabeticIndex::ImmutableIndex* immutableIndexFromPeer(jlong peer) {
- return reinterpret_cast<icu::AlphabeticIndex::ImmutableIndex*>(static_cast<uintptr_t>(peer));
-}
-
-static jint ImmutableIndex_getBucketCount(JNIEnv*, jclass, jlong peer) {
- icu::AlphabeticIndex::ImmutableIndex* ii = immutableIndexFromPeer(peer);
- return ii->getBucketCount();
-}
-
-static jint ImmutableIndex_getBucketIndex(JNIEnv* env, jclass, jlong peer, jstring javaString) {
- icu::AlphabeticIndex::ImmutableIndex* ii = immutableIndexFromPeer(peer);
- ScopedJavaUnicodeString string(env, javaString);
- if (!string.valid()) {
- return -1;
- }
- UErrorCode status = U_ZERO_ERROR;
- jint result = ii->getBucketIndex(string.unicodeString(), status);
- if (maybeThrowIcuException(env, "AlphabeticIndex::ImmutableIndex::getBucketIndex", status)) {
- return -1;
- }
- return result;
-}
-
-static jstring ImmutableIndex_getBucketLabel(JNIEnv* env, jclass, jlong peer, jint index) {
- icu::AlphabeticIndex::ImmutableIndex* ii = immutableIndexFromPeer(peer);
- const icu::AlphabeticIndex::Bucket* bucket = ii->getBucket(index);
- if (bucket == NULL) {
- jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Invalid index: %d", index);
- return NULL;
- }
-
- // Return "" for the underflow/inflow/overflow buckets.
- if (bucket->getLabelType() != U_ALPHAINDEX_NORMAL) {
- return env->NewStringUTF("");
- }
-
- const icu::UnicodeString& label(bucket->getLabel());
- return env->NewString(label.getBuffer(), label.length());
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(AlphabeticIndex, create, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(AlphabeticIndex, destroy, "(J)V"),
- NATIVE_METHOD(AlphabeticIndex, getMaxLabelCount, "(J)I"),
- NATIVE_METHOD(AlphabeticIndex, setMaxLabelCount, "(JI)V"),
- NATIVE_METHOD(AlphabeticIndex, addLabels, "(JLjava/lang/String;)V"),
- NATIVE_METHOD(AlphabeticIndex, addLabelRange, "(JII)V"),
- NATIVE_METHOD(AlphabeticIndex, getBucketCount, "(J)I"),
- NATIVE_METHOD(AlphabeticIndex, getBucketIndex, "(JLjava/lang/String;)I"),
- NATIVE_METHOD(AlphabeticIndex, getBucketLabel, "(JI)Ljava/lang/String;"),
- NATIVE_METHOD(AlphabeticIndex, buildImmutableIndex, "(J)J"),
-};
-static JNINativeMethod gImmutableIndexMethods[] = {
- NATIVE_METHOD(ImmutableIndex, getBucketCount, "(J)I"),
- NATIVE_METHOD(ImmutableIndex, getBucketIndex, "(JLjava/lang/String;)I"),
- NATIVE_METHOD(ImmutableIndex, getBucketLabel, "(JI)Ljava/lang/String;"),
-};
-void register_libcore_icu_AlphabeticIndex(JNIEnv* env) {
- jniRegisterNativeMethods(env, "libcore/icu/AlphabeticIndex", gMethods, NELEM(gMethods));
- jniRegisterNativeMethods(env, "libcore/icu/AlphabeticIndex$ImmutableIndex", gImmutableIndexMethods, NELEM(gImmutableIndexMethods));
-}
diff --git a/luni/src/main/native/libcore_icu_NativeIDN.cpp b/luni/src/main/native/libcore_icu_NativeIDN.cpp
deleted file mode 100644
index 43f3ce5..0000000
--- a/luni/src/main/native/libcore_icu_NativeIDN.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#define LOG_TAG "NativeIDN"
-
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "ScopedStringChars.h"
-#include "unicode/uidna.h"
-
-static bool isLabelSeparator(const UChar ch) {
- switch (ch) {
- case 0x3002: // ideographic full stop
- case 0xff0e: // fullwidth full stop
- case 0xff61: // halfwidth ideographic full stop
- return true;
- default:
- return false;
- }
-}
-
-static jstring NativeIDN_convertImpl(JNIEnv* env, jclass, jstring javaSrc, jint flags, jboolean toAscii) {
- ScopedStringChars src(env, javaSrc);
- if (src.get() == NULL) {
- return NULL;
- }
- UChar dst[256];
- UErrorCode status = U_ZERO_ERROR;
-
- // We're stuck implementing IDNA-2003 for now since that's what we specify.
- //
- // TODO: Change our spec to IDNA-2008 + UTS-46 compatibility processing if
- // it's safe enough.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- size_t resultLength = toAscii
- ? uidna_IDNToASCII(src.get(), src.size(), &dst[0], sizeof(dst), flags, NULL, &status)
- : uidna_IDNToUnicode(src.get(), src.size(), &dst[0], sizeof(dst), flags, NULL, &status);
-#pragma GCC diagnostic pop
-
- if (U_FAILURE(status)) {
- jniThrowException(env, "java/lang/IllegalArgumentException", u_errorName(status));
- return NULL;
- }
- if (!toAscii) {
- // ICU only translates separators to ASCII for toASCII.
- // Java expects the translation for toUnicode too.
- // We may as well do this here, while the string is still mutable.
- for (size_t i = 0; i < resultLength; ++i) {
- if (isLabelSeparator(dst[i])) {
- dst[i] = '.';
- }
- }
- }
- return env->NewString(&dst[0], resultLength);
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(NativeIDN, convertImpl, "(Ljava/lang/String;IZ)Ljava/lang/String;"),
-};
-void register_libcore_icu_NativeIDN(JNIEnv* env) {
- jniRegisterNativeMethods(env, "libcore/icu/NativeIDN", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/libcore_icu_NativeNormalizer.cpp b/luni/src/main/native/libcore_icu_NativeNormalizer.cpp
deleted file mode 100644
index 2d5e282..0000000
--- a/luni/src/main/native/libcore_icu_NativeNormalizer.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#define LOG_TAG "NativeNormalizer"
-
-#include "IcuUtilities.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "ScopedJavaUnicodeString.h"
-#include "unicode/normlzr.h"
-
-static jstring NativeNormalizer_normalizeImpl(JNIEnv* env, jclass, jstring s, jint intMode) {
- ScopedJavaUnicodeString src(env, s);
- if (!src.valid()) {
- return NULL;
- }
- UNormalizationMode mode = static_cast<UNormalizationMode>(intMode);
- UErrorCode status = U_ZERO_ERROR;
- icu::UnicodeString dst;
- icu::Normalizer::normalize(src.unicodeString(), mode, 0, dst, status);
- maybeThrowIcuException(env, "Normalizer::normalize", status);
- return dst.isBogus() ? NULL : env->NewString(dst.getBuffer(), dst.length());
-}
-
-static jboolean NativeNormalizer_isNormalizedImpl(JNIEnv* env, jclass, jstring s, jint intMode) {
- ScopedJavaUnicodeString src(env, s);
- if (!src.valid()) {
- return JNI_FALSE;
- }
- UNormalizationMode mode = static_cast<UNormalizationMode>(intMode);
- UErrorCode status = U_ZERO_ERROR;
- UBool result = icu::Normalizer::isNormalized(src.unicodeString(), mode, status);
- maybeThrowIcuException(env, "Normalizer::isNormalized", status);
- return result;
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(NativeNormalizer, normalizeImpl, "(Ljava/lang/String;I)Ljava/lang/String;"),
- NATIVE_METHOD(NativeNormalizer, isNormalizedImpl, "(Ljava/lang/String;I)Z"),
-};
-void register_libcore_icu_NativeNormalizer(JNIEnv* env) {
- jniRegisterNativeMethods(env, "libcore/icu/NativeNormalizer", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/libcore_icu_NativePluralRules.cpp b/luni/src/main/native/libcore_icu_NativePluralRules.cpp
deleted file mode 100644
index f278485..0000000
--- a/luni/src/main/native/libcore_icu_NativePluralRules.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#define LOG_TAG "NativePluralRules"
-
-#include "IcuUtilities.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "ScopedUtfChars.h"
-#include "unicode/plurrule.h"
-
-#include <string>
-
-static icu::PluralRules* toPluralRules(jlong address) {
- return reinterpret_cast<icu::PluralRules*>(static_cast<uintptr_t>(address));
-}
-
-static void NativePluralRules_finalizeImpl(JNIEnv*, jclass, jlong address) {
- delete toPluralRules(address);
-}
-
-static jlong NativePluralRules_forLocaleImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
- // The icu4c PluralRules returns a "other: n" default rule for the deprecated locales Java uses.
- // Work around this by translating back to the current language codes.
- std::string localeName(ScopedUtfChars(env, javaLocaleName).c_str());
- if (localeName[0] == 'i' && localeName[1] == 'w') {
- localeName[0] = 'h';
- localeName[1] = 'e';
- } else if (localeName[0] == 'i' && localeName[1] == 'n') {
- localeName[0] = 'i';
- localeName[1] = 'd';
- } else if (localeName[0] == 'j' && localeName[1] == 'i') {
- localeName[0] = 'y';
- localeName[1] = 'i';
- }
-
- icu::Locale locale = icu::Locale::createFromName(localeName.c_str());
- UErrorCode status = U_ZERO_ERROR;
- icu::PluralRules* result = icu::PluralRules::forLocale(locale, status);
- maybeThrowIcuException(env, "PluralRules::forLocale", status);
- return reinterpret_cast<uintptr_t>(result);
-}
-
-static jint NativePluralRules_quantityForIntImpl(JNIEnv*, jclass, jlong address, jint value) {
- icu::UnicodeString keyword = toPluralRules(address)->select(value);
- if (keyword == "zero") {
- return 0;
- } else if (keyword == "one") {
- return 1;
- } else if (keyword == "two") {
- return 2;
- } else if (keyword == "few") {
- return 3;
- } else if (keyword == "many") {
- return 4;
- } else {
- return 5;
- }
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(NativePluralRules, finalizeImpl, "(J)V"),
- NATIVE_METHOD(NativePluralRules, forLocaleImpl, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativePluralRules, quantityForIntImpl, "(JI)I"),
-};
-void register_libcore_icu_NativePluralRules(JNIEnv* env) {
- jniRegisterNativeMethods(env, "libcore/icu/NativePluralRules", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/libcore_icu_Transliterator.cpp b/luni/src/main/native/libcore_icu_Transliterator.cpp
deleted file mode 100644
index ae21565..0000000
--- a/luni/src/main/native/libcore_icu_Transliterator.cpp
+++ /dev/null
@@ -1,73 +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.
- */
-
-#define LOG_TAG "Transliterator"
-
-#include "IcuUtilities.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "ScopedJavaUnicodeString.h"
-#include "unicode/translit.h"
-
-static icu::Transliterator* fromPeer(jlong peer) {
- return reinterpret_cast<icu::Transliterator*>(static_cast<uintptr_t>(peer));
-}
-
-static jlong Transliterator_create(JNIEnv* env, jclass, jstring javaId) {
- ScopedJavaUnicodeString id(env, javaId);
- if (!id.valid()) {
- return 0;
- }
- UErrorCode status = U_ZERO_ERROR;
- icu::Transliterator* t = icu::Transliterator::createInstance(id.unicodeString(), UTRANS_FORWARD, status);
- if (maybeThrowIcuException(env, "Transliterator::createInstance", status)) {
- return 0;
- }
- return reinterpret_cast<uintptr_t>(t);
-}
-
-static void Transliterator_destroy(JNIEnv*, jclass, jlong peer) {
- delete fromPeer(peer);
-}
-
-static jobjectArray Transliterator_getAvailableIDs(JNIEnv* env, jclass) {
- UErrorCode status = U_ZERO_ERROR;
- icu::StringEnumeration* e = icu::Transliterator::getAvailableIDs(status);
- return fromStringEnumeration(env, status, "Transliterator::getAvailableIDs", e);
-}
-
-static jstring Transliterator_transliterate(JNIEnv* env, jclass, jlong peer, jstring javaString) {
- icu::Transliterator* t = fromPeer(peer);
- ScopedJavaUnicodeString string(env, javaString);
- if (!string.valid()) {
- return NULL;
- }
-
- icu::UnicodeString& s(string.unicodeString());
- t->transliterate(s);
- return env->NewString(s.getBuffer(), s.length());
-}
-
-static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(Transliterator, create, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(Transliterator, destroy, "(J)V"),
- NATIVE_METHOD(Transliterator, getAvailableIDs, "()[Ljava/lang/String;"),
- NATIVE_METHOD(Transliterator, transliterate, "(JLjava/lang/String;)Ljava/lang/String;"),
-};
-void register_libcore_icu_Transliterator(JNIEnv* env) {
- jniRegisterNativeMethods(env, "libcore/icu/Transliterator", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index f6af483..bfe2380 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -45,20 +45,17 @@
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
-#ifndef __APPLE__
#include <sys/prctl.h>
-#endif
#include <sys/socket.h>
#include <sys/stat.h>
-#ifdef __APPLE__
-#include <sys/statvfs.h>
-#endif
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
+#include <sys/un.h>
#include <sys/utsname.h>
#include <sys/wait.h>
+#include <sys/xattr.h>
#include <termios.h>
#include <unistd.h>
#include <memory>
@@ -138,9 +135,9 @@
*/
#define NET_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ...) ({ \
return_type _rc = -1; \
+ int _syscallErrno; \
do { \
bool _wasSignaled; \
- int _syscallErrno; \
{ \
int _fd = jniGetFDFromFileDescriptor(jni_env, java_fd); \
AsynchronousCloseMonitor _monitor(_fd); \
@@ -159,6 +156,10 @@
break; \
} \
} while (_rc == -1); /* _syscallErrno == EINTR && !_wasSignaled */ \
+ if (_rc == -1) { \
+ /* If the syscall failed, re-set errno: throwing an exception might have modified it. */ \
+ errno = _syscallErrno; \
+ } \
_rc; })
/**
@@ -173,9 +174,9 @@
*/
#define IO_FAILURE_RETRY(jni_env, return_type, syscall_name, java_fd, ...) ({ \
return_type _rc = -1; \
+ int _syscallErrno; \
do { \
bool _wasSignaled; \
- int _syscallErrno; \
{ \
int _fd = jniGetFDFromFileDescriptor(jni_env, java_fd); \
AsynchronousCloseMonitor _monitor(_fd); \
@@ -194,6 +195,10 @@
break; \
} \
} while (_rc == -1); /* && _syscallErrno == EINTR && !_wasSignaled */ \
+ if (_rc == -1) { \
+ /* If the syscall failed, re-set errno: throwing an exception might have modified it. */ \
+ errno = _syscallErrno; \
+ } \
_rc; })
#define NULL_ADDR_OK true
@@ -316,8 +321,40 @@
std::vector<ScopedT*> mScopedBuffers;
};
-static jobject makeSocketAddress(JNIEnv* env, const sockaddr_storage& ss) {
- if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6 || ss.ss_family == AF_UNIX) {
+/**
+ * Returns a jbyteArray containing the sockaddr_un.sun_path from ss. As per unix(7) sa_len should be
+ * the length of ss as returned by getsockname(2), getpeername(2), or accept(2).
+ * If the returned array is of length 0 the sockaddr_un refers to an unnamed socket.
+ * A null pointer is returned in the event of an error. See unix(7) for more information.
+ */
+static jbyteArray getUnixSocketPath(JNIEnv* env, const sockaddr_storage& ss,
+ const socklen_t& sa_len) {
+ if (ss.ss_family != AF_UNIX) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+ "getUnixSocketPath unsupported ss_family: %i", ss.ss_family);
+ return NULL;
+ }
+
+ const struct sockaddr_un* un_addr = reinterpret_cast<const struct sockaddr_un*>(&ss);
+ // The length of sun_path is sa_len minus the length of the overhead (ss_family).
+ // See unix(7) for details. This calculation must match that of socket_make_sockaddr_un() in
+ // socket_local_client.c and javaUnixSocketAddressToSockaddr() to interoperate.
+ size_t pathLength = sa_len - offsetof(struct sockaddr_un, sun_path);
+
+ jbyteArray javaSunPath = env->NewByteArray(pathLength);
+ if (javaSunPath == NULL) {
+ return NULL;
+ }
+
+ if (pathLength > 0) {
+ env->SetByteArrayRegion(javaSunPath, 0, pathLength,
+ reinterpret_cast<const jbyte*>(&un_addr->sun_path));
+ }
+ return javaSunPath;
+}
+
+static jobject makeSocketAddress(JNIEnv* env, const sockaddr_storage& ss, const socklen_t sa_len) {
+ if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) {
jint port;
jobject inetAddress = sockaddrToInetAddress(env, ss, &port);
if (inetAddress == NULL) {
@@ -326,6 +363,15 @@
static jmethodID ctor = env->GetMethodID(JniConstants::inetSocketAddressClass,
"<init>", "(Ljava/net/InetAddress;I)V");
return env->NewObject(JniConstants::inetSocketAddressClass, ctor, inetAddress, port);
+ } else if (ss.ss_family == AF_UNIX) {
+ static jmethodID ctor = env->GetMethodID(JniConstants::unixSocketAddressClass,
+ "<init>", "([B)V");
+
+ jbyteArray javaSunPath = getUnixSocketPath(env, ss, sa_len);
+ if (!javaSunPath) {
+ return NULL;
+ }
+ return env->NewObject(JniConstants::unixSocketAddressClass, ctor, javaSunPath);
} else if (ss.ss_family == AF_NETLINK) {
const struct sockaddr_nl* nl_addr = reinterpret_cast<const struct sockaddr_nl*>(&ss);
static jmethodID ctor = env->GetMethodID(JniConstants::netlinkSocketAddressClass,
@@ -380,13 +426,6 @@
}
static jobject makeStructStatVfs(JNIEnv* env, const struct statvfs& sb) {
-#if defined(__APPLE__)
- // Mac OS has no f_namelen field in struct statfs.
- jlong max_name_length = 255; // __DARWIN_MAXNAMLEN
-#else
- jlong max_name_length = static_cast<jlong>(sb.f_namemax);
-#endif
-
static jmethodID ctor = env->GetMethodID(JniConstants::structStatVfsClass, "<init>",
"(JJJJJJJJJJJ)V");
return env->NewObject(JniConstants::structStatVfsClass, ctor,
@@ -400,7 +439,7 @@
static_cast<jlong>(sb.f_favail),
static_cast<jlong>(sb.f_fsid),
static_cast<jlong>(sb.f_flag),
- max_name_length);
+ static_cast<jlong>(sb.f_namemax));
}
static jobject makeStructLinger(JNIEnv* env, const struct linger& l) {
@@ -415,13 +454,8 @@
}
static jobject makeStructUcred(JNIEnv* env, const struct ucred& u __unused) {
-#ifdef __APPLE__
- jniThrowException(env, "java/lang/UnsupportedOperationException", "unimplemented support for ucred on a Mac");
- return NULL;
-#else
static jmethodID ctor = env->GetMethodID(JniConstants::structUcredClass, "<init>", "(III)V");
return env->NewObject(JniConstants::structUcredClass, ctor, u.pid, u.uid, u.gid);
-#endif
}
static jobject makeStructUtsname(JNIEnv* env, const struct utsname& buf) {
@@ -447,8 +481,25 @@
return true;
}
-static bool fillInetSocketAddress(JNIEnv* env, jint rc, jobject javaInetSocketAddress, const sockaddr_storage& ss) {
- if (rc == -1 || javaInetSocketAddress == NULL) {
+static bool fillUnixSocketAddress(JNIEnv* env, jobject javaUnixSocketAddress,
+ const sockaddr_storage& ss, const socklen_t& sa_len) {
+ if (javaUnixSocketAddress == NULL) {
+ return true;
+ }
+ jbyteArray javaSunPath = getUnixSocketPath(env, ss, sa_len);
+ if (!javaSunPath) {
+ return false;
+ }
+
+ static jfieldID sunPathFid =
+ env->GetFieldID(JniConstants::unixSocketAddressClass, "sun_path", "[B");
+ env->SetObjectField(javaUnixSocketAddress, sunPathFid, javaSunPath);
+ return true;
+}
+
+static bool fillInetSocketAddress(JNIEnv* env, jobject javaInetSocketAddress,
+ const sockaddr_storage& ss) {
+ if (javaInetSocketAddress == NULL) {
return true;
}
// Fill out the passed-in InetSocketAddress with the sender's IP address and port number.
@@ -464,6 +515,23 @@
return true;
}
+static bool fillSocketAddress(JNIEnv* env, jobject javaSocketAddress, const sockaddr_storage& ss,
+ const socklen_t& sa_len) {
+ if (javaSocketAddress == NULL) {
+ return true;
+ }
+
+ if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
+ return fillInetSocketAddress(env, javaSocketAddress, ss);
+ } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::unixSocketAddressClass)) {
+ return fillUnixSocketAddress(env, javaSocketAddress, ss, sa_len);
+ }
+ jniThrowException(env, "java/lang/UnsupportedOperationException",
+ "unsupported SocketAddress subclass");
+ return false;
+
+}
+
static void javaInetSocketAddressToInetAddressAndPort(
JNIEnv* env, jobject javaInetSocketAddress, jobject& javaInetAddress, jint& port) {
static jfieldID addressFid = env->GetFieldID(
@@ -496,6 +564,31 @@
return true;
}
+static bool javaUnixSocketAddressToSockaddr(
+ JNIEnv* env, jobject javaUnixSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
+ static jfieldID sunPathFid = env->GetFieldID(
+ JniConstants::unixSocketAddressClass, "sun_path", "[B");
+
+ struct sockaddr_un* un_addr = reinterpret_cast<struct sockaddr_un*>(&ss);
+ memset (un_addr, 0, sizeof(sockaddr_un));
+ un_addr->sun_family = AF_UNIX;
+
+ jbyteArray javaSunPath = (jbyteArray) env->GetObjectField(javaUnixSocketAddress, sunPathFid);
+ jsize pathLength = env->GetArrayLength(javaSunPath);
+ if ((size_t) pathLength > sizeof(sockaddr_un::sun_path)) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+ "sun_path too long: max=%i, is=%i",
+ sizeof(sockaddr_un::sun_path), pathLength);
+ return false;
+ }
+ env->GetByteArrayRegion(javaSunPath, 0, pathLength, (jbyte*) un_addr->sun_path);
+ // sa_len is sun_path plus the length of the overhead (ss_family_t). See unix(7) for
+ // details. This calculation must match that of socket_make_sockaddr_un() in
+ // socket_local_client.c and getUnixSocketPath() to interoperate.
+ sa_len = offsetof(struct sockaddr_un, sun_path) + pathLength;
+ return true;
+}
+
static bool javaPacketSocketAddressToSockaddr(
JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
static jfieldID protocolFid = env->GetFieldID(
@@ -545,6 +638,8 @@
return javaInetSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
} else if (env->IsInstanceOf(javaSocketAddress, JniConstants::packetSocketAddressClass)) {
return javaPacketSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
+ } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::unixSocketAddressClass)) {
+ return javaUnixSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
}
jniThrowException(env, "java/lang/UnsupportedOperationException",
"unsupported SocketAddress subclass");
@@ -578,7 +673,7 @@
throwErrnoException(env, is_sockname ? "getsockname" : "getpeername");
return NULL;
}
- return makeSocketAddress(env, ss);
+ return makeSocketAddress(env, ss, byteCount);
}
class Passwd {
@@ -617,14 +712,14 @@
struct passwd* mResult;
};
-static jobject Posix_accept(JNIEnv* env, jobject, jobject javaFd, jobject javaInetSocketAddress) {
+static jobject Posix_accept(JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
sockaddr_storage ss;
socklen_t sl = sizeof(ss);
memset(&ss, 0, sizeof(ss));
- sockaddr* peer = (javaInetSocketAddress != NULL) ? reinterpret_cast<sockaddr*>(&ss) : NULL;
- socklen_t* peerLength = (javaInetSocketAddress != NULL) ? &sl : 0;
+ sockaddr* peer = (javaSocketAddress != NULL) ? reinterpret_cast<sockaddr*>(&ss) : NULL;
+ socklen_t* peerLength = (javaSocketAddress != NULL) ? &sl : 0;
jint clientFd = NET_FAILURE_RETRY(env, int, accept, javaFd, peer, peerLength);
- if (clientFd == -1 || !fillInetSocketAddress(env, clientFd, javaInetSocketAddress, ss)) {
+ if (clientFd == -1 || !fillSocketAddress(env, javaSocketAddress, ss, *peerLength)) {
close(clientFd);
return NULL;
}
@@ -1042,15 +1137,7 @@
}
static jint Posix_gettid(JNIEnv* env __unused, jobject) {
-#if defined(__APPLE__)
- uint64_t owner;
- int rc = pthread_threadid_np(NULL, &owner); // Requires Mac OS 10.6
- if (rc != 0) {
- throwErrnoException(env, "gettid");
- return 0;
- }
- return static_cast<jint>(owner);
-#elif defined(__BIONIC__)
+#if defined(__BIONIC__)
return TEMP_FAILURE_RETRY(gettid());
#else
return syscall(__NR_gettid);
@@ -1061,6 +1148,28 @@
return getuid();
}
+static jint Posix_getxattr(JNIEnv* env, jobject, jstring javaPath,
+ jstring javaName, jbyteArray javaOutValue) {
+ ScopedUtfChars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return -1;
+ }
+ ScopedUtfChars name(env, javaName);
+ if (name.c_str() == NULL) {
+ return -1;
+ }
+ ScopedBytesRW outValue(env, javaOutValue);
+ if (outValue.get() == NULL) {
+ return -1;
+ }
+ size_t outValueLength = env->GetArrayLength(javaOutValue);
+ ssize_t size = getxattr(path.c_str(), name.c_str(), outValue.get(), outValueLength);
+ if (size < 0) {
+ throwErrnoException(env, "getxattr");
+ }
+ return size;
+}
+
static jstring Posix_if_indextoname(JNIEnv* env, jobject, jint index) {
char buf[IF_NAMESIZE];
char* name = if_indextoname(index, buf);
@@ -1220,10 +1329,6 @@
}
static jobjectArray Posix_pipe2(JNIEnv* env, jobject, jint flags __unused) {
-#ifdef __APPLE__
- jniThrowException(env, "java/lang/UnsupportedOperationException", "no pipe2 on Mac OS");
- return NULL;
-#else
int fds[2];
throwIfMinusOne(env, "pipe2", TEMP_FAILURE_RETRY(pipe2(&fds[0], flags)));
jobjectArray result = env->NewObjectArray(2, JniConstants::fileDescriptorClass, NULL);
@@ -1241,7 +1346,6 @@
}
}
return result;
-#endif
}
static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint timeoutMs) {
@@ -1327,32 +1431,22 @@
static void Posix_posix_fallocate(JNIEnv* env, jobject, jobject javaFd __unused,
jlong offset __unused, jlong length __unused) {
-#ifdef __APPLE__
- jniThrowException(env, "java/lang/UnsupportedOperationException",
- "fallocate doesn't exist on a Mac");
-#else
int fd = jniGetFDFromFileDescriptor(env, javaFd);
while ((errno = posix_fallocate64(fd, offset, length)) == EINTR) {
}
if (errno != 0) {
throwErrnoException(env, "posix_fallocate");
}
-#endif
}
static jint Posix_prctl(JNIEnv* env, jobject, jint option __unused, jlong arg2 __unused,
jlong arg3 __unused, jlong arg4 __unused, jlong arg5 __unused) {
-#ifdef __APPLE__
- jniThrowException(env, "java/lang/UnsupportedOperationException", "prctl doesn't exist on a Mac");
- return 0;
-#else
int result = TEMP_FAILURE_RETRY(prctl(static_cast<int>(option),
static_cast<unsigned long>(arg2),
static_cast<unsigned long>(arg3),
static_cast<unsigned long>(arg4),
static_cast<unsigned long>(arg5)));
return throwIfMinusOne(env, "prctl", result);
-#endif
}
static jint Posix_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) {
@@ -1412,7 +1506,10 @@
sockaddr* from = (javaInetSocketAddress != NULL) ? reinterpret_cast<sockaddr*>(&ss) : NULL;
socklen_t* fromLength = (javaInetSocketAddress != NULL) ? &sl : 0;
jint recvCount = NET_FAILURE_RETRY(env, ssize_t, recvfrom, javaFd, bytes.get() + byteOffset, byteCount, flags, from, fromLength);
- fillInetSocketAddress(env, recvCount, javaInetSocketAddress, ss);
+ if (recvCount == -1) {
+ return recvCount;
+ }
+ fillInetSocketAddress(env, javaInetSocketAddress, ss);
return recvCount;
}
@@ -1424,6 +1521,22 @@
throwIfMinusOne(env, "remove", TEMP_FAILURE_RETRY(remove(path.c_str())));
}
+static void Posix_removexattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName) {
+ ScopedUtfChars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return;
+ }
+ ScopedUtfChars name(env, javaName);
+ if (name.c_str() == NULL) {
+ return;
+ }
+
+ int res = removexattr(path.c_str(), name.c_str());
+ if (res < 0) {
+ throwErrnoException(env, "removexattr");
+ }
+}
+
static void Posix_rename(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
ScopedUtfChars oldPath(env, javaOldPath);
if (oldPath.c_str() == NULL) {
@@ -1550,12 +1663,6 @@
throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
}
-#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED < 1070
-// Mac OS didn't support modern multicast APIs until 10.7.
-static void Posix_setsockoptIpMreqn(JNIEnv*, jobject, jobject, jint, jint, jint) { abort(); }
-static void Posix_setsockoptGroupReq(JNIEnv*, jobject, jobject, jint, jint, jobject) { abort(); }
-static void Posix_setsockoptGroupSourceReq(JNIEnv*, jobject, jobject, jint, jint, jobject) { abort(); }
-#else
static void Posix_setsockoptIpMreqn(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
ip_mreqn req;
memset(&req, 0, sizeof(req));
@@ -1638,7 +1745,6 @@
}
throwIfMinusOne(env, "setsockopt", rc);
}
-#endif
static void Posix_setsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaLinger) {
static jfieldID lOnoffFid = env->GetFieldID(JniConstants::structLingerClass, "l_onoff", "I");
@@ -1664,6 +1770,27 @@
throwIfMinusOne(env, "setuid", TEMP_FAILURE_RETRY(setuid(uid)));
}
+static void Posix_setxattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName,
+ jbyteArray javaValue, jint flags) {
+ ScopedUtfChars path(env, javaPath);
+ if (path.c_str() == NULL) {
+ return;
+ }
+ ScopedUtfChars name(env, javaName);
+ if (name.c_str() == NULL) {
+ return;
+ }
+ ScopedBytesRO value(env, javaValue);
+ if (value.get() == NULL) {
+ return;
+ }
+ size_t valueLength = env->GetArrayLength(javaValue);
+ int res = setxattr(path.c_str(), name.c_str(), value.get(), valueLength, flags);
+ if (res < 0) {
+ throwErrnoException(env, "setxattr");
+ }
+}
+
static void Posix_shutdown(JNIEnv* env, jobject, jobject javaFd, jint how) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
throwIfMinusOne(env, "shutdown", TEMP_FAILURE_RETRY(shutdown(fd, how)));
@@ -1758,6 +1885,14 @@
return makeStructUtsname(env, buf);
}
+static void Posix_unlink(JNIEnv* env, jobject, jstring javaPathname) {
+ ScopedUtfChars pathname(env, javaPathname);
+ if (pathname.c_str() == NULL) {
+ return;
+ }
+ throwIfMinusOne(env, "unlink", unlink(pathname.c_str()));
+}
+
static void Posix_unsetenv(JNIEnv* env, jobject, jstring javaName) {
ScopedUtfChars name(env, javaName);
if (name.c_str() == NULL) {
@@ -1796,7 +1931,7 @@
{ #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName ## variant) }
static JNINativeMethod gMethods[] = {
- NATIVE_METHOD(Posix, accept, "(Ljava/io/FileDescriptor;Ljava/net/InetSocketAddress;)Ljava/io/FileDescriptor;"),
+ NATIVE_METHOD(Posix, accept, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Posix, access, "(Ljava/lang/String;I)Z"),
NATIVE_METHOD(Posix, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
NATIVE_METHOD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
@@ -1842,6 +1977,7 @@
NATIVE_METHOD(Posix, getsockoptUcred, "(Ljava/io/FileDescriptor;II)Landroid/system/StructUcred;"),
NATIVE_METHOD(Posix, gettid, "()I"),
NATIVE_METHOD(Posix, getuid, "()I"),
+ NATIVE_METHOD(Posix, getxattr, "(Ljava/lang/String;Ljava/lang/String;[B)I"),
NATIVE_METHOD(Posix, if_indextoname, "(I)Ljava/lang/String;"),
NATIVE_METHOD(Posix, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"),
NATIVE_METHOD(Posix, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"),
@@ -1873,6 +2009,7 @@
NATIVE_METHOD(Posix, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
NATIVE_METHOD(Posix, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"),
NATIVE_METHOD(Posix, remove, "(Ljava/lang/String;)V"),
+ NATIVE_METHOD(Posix, removexattr, "(Ljava/lang/String;Ljava/lang/String;)V"),
NATIVE_METHOD(Posix, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
NATIVE_METHOD(Posix, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/util/MutableLong;J)J"),
NATIVE_METHOD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"),
@@ -1894,6 +2031,7 @@
NATIVE_METHOD(Posix, setsockoptLinger, "(Ljava/io/FileDescriptor;IILandroid/system/StructLinger;)V"),
NATIVE_METHOD(Posix, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V"),
NATIVE_METHOD(Posix, setuid, "(I)V"),
+ NATIVE_METHOD(Posix, setxattr, "(Ljava/lang/String;Ljava/lang/String;[BI)V"),
NATIVE_METHOD(Posix, shutdown, "(Ljava/io/FileDescriptor;I)V"),
NATIVE_METHOD(Posix, socket, "(III)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Posix, socketpair, "(IIILjava/io/FileDescriptor;Ljava/io/FileDescriptor;)V"),
@@ -1907,6 +2045,7 @@
NATIVE_METHOD(Posix, tcsendbreak, "(Ljava/io/FileDescriptor;I)V"),
NATIVE_METHOD(Posix, umaskImpl, "(I)I"),
NATIVE_METHOD(Posix, uname, "()Landroid/system/StructUtsname;"),
+ NATIVE_METHOD(Posix, unlink, "(Ljava/lang/String;)V"),
NATIVE_METHOD(Posix, unsetenv, "(Ljava/lang/String;)V"),
NATIVE_METHOD(Posix, waitpid, "(ILandroid/util/MutableInt;I)I"),
NATIVE_METHOD(Posix, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
diff --git a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
index 48defc1..f6f812c 100644
--- a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
+++ b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
@@ -31,7 +31,7 @@
#include <memory>
#include <string.h>
-#include <libexpat/expat.h>
+#include <expat.h>
#define BUCKET_COUNT 128
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 78ec37a..b227793 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -27,7 +27,6 @@
java_lang_StringToReal.cpp \
java_lang_System.cpp \
java_math_NativeBN.cpp \
- java_text_Bidi.cpp \
java_util_jar_StrictJarFile.cpp \
java_util_regex_Matcher.cpp \
java_util_regex_Pattern.cpp \
@@ -35,16 +34,11 @@
java_util_zip_CRC32.cpp \
java_util_zip_Deflater.cpp \
java_util_zip_Inflater.cpp \
- libcore_icu_AlphabeticIndex.cpp \
libcore_icu_ICU.cpp \
libcore_icu_NativeCollation.cpp \
libcore_icu_NativeConverter.cpp \
libcore_icu_NativeDecimalFormat.cpp \
- libcore_icu_NativeIDN.cpp \
- libcore_icu_NativeNormalizer.cpp \
- libcore_icu_NativePluralRules.cpp \
libcore_icu_TimeZoneNames.cpp \
- libcore_icu_Transliterator.cpp \
libcore_io_AsynchronousCloseMonitor.cpp \
libcore_io_Memory.cpp \
libcore_io_Posix.cpp \
diff --git a/luni/src/test/java/android/system/UnixSocketAddressTest.java b/luni/src/test/java/android/system/UnixSocketAddressTest.java
new file mode 100644
index 0000000..f1b7fc2
--- /dev/null
+++ b/luni/src/test/java/android/system/UnixSocketAddressTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 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 junit.framework.TestCase;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+public class UnixSocketAddressTest extends TestCase {
+
+ public void testFilesystemSunPath() throws Exception {
+ String path = "/foo/bar";
+ UnixSocketAddress sa = UnixSocketAddress.createFileSystem(path);
+
+ byte[] abstractNameBytes = path.getBytes(StandardCharsets.UTF_8);
+ byte[] expected = new byte[abstractNameBytes.length + 1];
+ // See unix(7)
+ System.arraycopy(abstractNameBytes, 0, expected, 0, abstractNameBytes.length);
+ assertTrue(Arrays.equals(expected, sa.getSunPath()));
+ }
+
+ public void testUnnamedSunPath() throws Exception {
+ UnixSocketAddress sa = UnixSocketAddress.createUnnamed();
+ assertEquals(0, sa.getSunPath().length);
+ }
+
+ public void testAbstractSunPath() throws Exception {
+ String abstractName = "abstract";
+ UnixSocketAddress sa = UnixSocketAddress.createAbstract(abstractName);
+ byte[] abstractNameBytes = abstractName.getBytes(StandardCharsets.UTF_8);
+ byte[] expected = new byte[abstractNameBytes.length + 1];
+ // See unix(7)
+ System.arraycopy(abstractNameBytes, 0, expected, 1, abstractNameBytes.length);
+ assertTrue(Arrays.equals(expected, sa.getSunPath()));
+ }
+}
diff --git a/luni/src/test/java/libcore/icu/AlphabeticIndexTest.java b/luni/src/test/java/libcore/icu/AlphabeticIndexTest.java
deleted file mode 100644
index 6c7452d..0000000
--- a/luni/src/test/java/libcore/icu/AlphabeticIndexTest.java
+++ /dev/null
@@ -1,230 +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 libcore.icu;
-
-import java.util.Locale;
-
-public class AlphabeticIndexTest extends junit.framework.TestCase {
- private static AlphabeticIndex.ImmutableIndex createIndex(Locale locale) {
- return new AlphabeticIndex(locale).addLabels(Locale.US).getImmutableIndex();
- }
-
- private static void assertHasLabel(AlphabeticIndex.ImmutableIndex ii, String string, String expectedLabel) {
- int index = ii.getBucketIndex(string);
- String label = ii.getBucketLabel(index);
- assertEquals(expectedLabel, label);
- }
-
- public void test_en() throws Exception {
- // English [A-Z]
- AlphabeticIndex.ImmutableIndex en = createIndex(Locale.ENGLISH);
- assertHasLabel(en, "Allen", "A");
- assertHasLabel(en, "allen", "A");
- }
-
- public void test_ja() throws Exception {
- AlphabeticIndex.ImmutableIndex ja = createIndex(Locale.JAPANESE);
-
- // Japanese
- // sorts hiragana/katakana, Kanji/Chinese, English, other
- // …, あ, か, さ, た, な, は, ま, や, ら, わ, …
- // hiragana "a"
- assertHasLabel(ja, "Allen", "A");
- assertHasLabel(ja, "\u3041", "\u3042");
- // katakana "a"
- assertHasLabel(ja, "\u30a1", "\u3042");
-
- // Kanji (sorts to inflow section)
- assertHasLabel(ja, "\u65e5", "");
-
- // http://bugs.icu-project.org/trac/ticket/10423 / http://b/10809397
- assertHasLabel(ja, "\u95c7", "");
- assertHasLabel(ja, "\u308f", "わ");
-
- // English
- assertHasLabel(ja, "Smith", "S");
-
- // Chinese (sorts to inflow section)
- assertHasLabel(ja, "\u6c88" /* Shen/Chen */, "");
-
- // Korean Hangul (sorts to overflow section)
- assertHasLabel(ja, "\u1100", "");
- }
-
- public void test_ko() throws Exception {
- // Korean (sorts Korean, then English)
- // …, ᄀ, ᄂ, ᄃ, ᄅ, ᄆ, ᄇ, ᄉ, ᄋ, ᄌ, ᄎ, ᄏ, ᄐ, ᄑ, ᄒ, …
- AlphabeticIndex.ImmutableIndex ko = createIndex(Locale.KOREAN);
- assertHasLabel(ko, "\u1100", "\u3131");
- assertHasLabel(ko, "\u3131", "\u3131");
- assertHasLabel(ko, "\u1101", "\u3131");
- assertHasLabel(ko, "\u1161", "\u314e");
- }
-
- public void test_cs() throws Exception {
- // Czech
- // …, [A-C], Č,[D-H], CH, [I-R], Ř, S, Š, [T-Z], Ž, …
- AlphabeticIndex.ImmutableIndex cs = createIndex(new Locale("cs"));
- assertHasLabel(cs, "Cena", "C");
- assertHasLabel(cs, "Čáp", "\u010c");
- assertHasLabel(cs, "Ruda", "R");
- assertHasLabel(cs, "Řada", "\u0158");
- assertHasLabel(cs, "Selka", "S");
- assertHasLabel(cs, "Šála", "\u0160");
- assertHasLabel(cs, "Zebra", "Z");
- assertHasLabel(cs, "Žába", "\u017d");
- assertHasLabel(cs, "Chata", "CH");
- }
-
- public void test_fr() throws Exception {
- // French: [A-Z] (no accented chars)
- AlphabeticIndex.ImmutableIndex fr = createIndex(Locale.FRENCH);
- assertHasLabel(fr, "Øfer", "O");
- assertHasLabel(fr, "Œster", "O");
- }
-
- public void test_da() throws Exception {
- // Danish: [A-Z], Æ, Ø, Å
- AlphabeticIndex.ImmutableIndex da = createIndex(new Locale("da"));
- assertHasLabel(da, "Ænes", "\u00c6");
- assertHasLabel(da, "Øfer", "\u00d8");
- assertHasLabel(da, "Œster", "\u00d8");
- assertHasLabel(da, "Ågård", "\u00c5");
- }
-
- public void test_de() throws Exception {
- // German: [A-Z] (no ß or umlauted characters in standard alphabet)
- AlphabeticIndex.ImmutableIndex de = createIndex(Locale.GERMAN);
- assertHasLabel(de, "ßind", "S");
- // We no longer split out "S", "Sch", and "St".
- assertHasLabel(de, "Sacher", "S");
- assertHasLabel(de, "Schiller", "S");
- assertHasLabel(de, "Steiff", "S");
- }
-
- public void test_th() throws Exception {
- // Thai (sorts English then Thai)
- // …, ก, ข, ฃ, ค, ฅ, ฆ, ง, จ, ฉ, ช, ซ, ฌ, ญ, ฎ, ฏ, ฐ, ฑ, ฒ, ณ, ด, ต, ถ, ท, ธ, น, บ, ป, ผ, ฝ, พ, ฟ, ภ, ม, ย, ร, ฤ, ล, ฦ, ว, ศ, ษ, ส, ห, ฬ, อ, ฮ, …,
- AlphabeticIndex.ImmutableIndex th = createIndex(new Locale("th"));
- assertHasLabel(th, "\u0e2d\u0e07\u0e04\u0e4c\u0e40\u0e25\u0e47\u0e01", "\u0e2d");
- assertHasLabel(th, "\u0e2a\u0e34\u0e07\u0e2b\u0e40\u0e2a\u0e19\u0e35", "\u0e2a");
- }
-
- public void test_ar() throws Exception {
- // Arabic (sorts English then Arabic)
- // …, ا, ب, ت, ث, ج, ح, خ, د, ذ, ر, ز, س, ش, ص, ض, ط, ظ, ع, غ, ف, ق, ك, ل, م, ن, ه, و, ي, …
- AlphabeticIndex.ImmutableIndex ar = createIndex(new Locale("ar"));
- assertHasLabel(ar, "\u0646\u0648\u0631", /* Noor */ "\u0646");
- }
-
- public void test_he() throws Exception {
- // Hebrew (sorts English then Hebrew)
- // …, א, ב, ג, ד, ה, ו, ז, ח, ט, י, כ, ל, מ, נ, ס, ע, פ, צ, ק, ר, ש, ת, …
- AlphabeticIndex.ImmutableIndex he = createIndex(new Locale("he"));
- assertHasLabel(he, "\u05e4\u05e8\u05d9\u05d3\u05de\u05df", "\u05e4");
- }
-
- public void test_zh_CN() throws Exception {
- // Simplified Chinese (default collator Pinyin): [A-Z]
- AlphabeticIndex.ImmutableIndex zh_CN = createIndex(new Locale("zh", "CN"));
-
- // Jia/Gu: should be, usually, 'J' for name collator and 'G' for apps/other
- assertHasLabel(zh_CN, "\u8d3e", "J");
-
- // Shen/Chen (simplified): should usually be 'S' for names and 'C' for apps/other.
- // icu4c does not specialize for names and defaults to 'C'.
- // Some OEMs prefer to default to 'S'.
- // We allow either to pass CTS since neither choice is right all the time.
- // assertHasLabel(zh_CN, "\u6c88", "C");
- String shenChenLabel = zh_CN.getBucketLabel(zh_CN.getBucketIndex("\u6c88"));
- assertTrue(shenChenLabel.equals("C") || shenChenLabel.equals("S"));
-
- // Shen/Chen (traditional)
- assertHasLabel(zh_CN, "\u700b", "S");
- }
-
- public void test_zh_HK() throws Exception {
- // Traditional Chinese (strokes).
- // …, [1-33, 35, 36, 39, 48]劃, …
- // Shen/Chen
- AlphabeticIndex.ImmutableIndex zh_HK = createIndex(new Locale("zh", "HK"));
- assertHasLabel(zh_HK, "\u6c88", "7\u5283");
- assertHasLabel(zh_HK, "\u700b", "18\u5283");
- // Jia/Gu
- assertHasLabel(zh_HK, "\u8d3e", "10\u5283");
- }
-
- public void test_constructor_NPE() throws Exception {
- try {
- new AlphabeticIndex(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_addLabels_NPE() throws Exception {
- AlphabeticIndex ai = new AlphabeticIndex(Locale.US);
- try {
- ai.addLabels(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- // ICU 51 default max label count is 99. Test to make sure can create an
- // index with a larger number of labels.
- public void test_setMaxLabelCount() throws Exception {
- final int MAX_LABEL_COUNT = 500;
- AlphabeticIndex ai = new AlphabeticIndex(Locale.US)
- .setMaxLabelCount(MAX_LABEL_COUNT)
- .addLabels(Locale.JAPANESE)
- .addLabels(Locale.KOREAN)
- .addLabels(new Locale("th"))
- .addLabels(new Locale("ar"))
- .addLabels(new Locale("he"))
- .addLabels(new Locale("el"))
- .addLabels(new Locale("ru"));
- assertEquals(MAX_LABEL_COUNT, ai.getMaxLabelCount());
- assertEquals(208, ai.getBucketCount());
- AlphabeticIndex.ImmutableIndex ii = ai.getImmutableIndex();
- assertEquals(ai.getBucketCount(), ii.getBucketCount());
- }
-
- public void test_getBucketIndex_NPE() throws Exception {
- AlphabeticIndex.ImmutableIndex ii = createIndex(Locale.US);
- try {
- ii.getBucketIndex(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_getBucketLabel_invalid() throws Exception {
- AlphabeticIndex.ImmutableIndex ii = createIndex(Locale.US);
- try {
- ii.getBucketLabel(-1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- ii.getBucketLabel(123456);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-}
diff --git a/luni/src/test/java/libcore/icu/NativePluralRulesTest.java b/luni/src/test/java/libcore/icu/NativePluralRulesTest.java
deleted file mode 100644
index 76179b4..0000000
--- a/luni/src/test/java/libcore/icu/NativePluralRulesTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2009 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 libcore.icu;
-
-import java.util.Locale;
-
-public class NativePluralRulesTest extends junit.framework.TestCase {
- public void testNegatives() throws Exception {
- // icu4c's behavior changed, but we prefer to preserve compatibility.
- NativePluralRules en_US = NativePluralRules.forLocale(new Locale("en", "US"));
- assertEquals(NativePluralRules.OTHER, en_US.quantityForInt(2));
- assertEquals(NativePluralRules.ONE, en_US.quantityForInt(1));
- assertEquals(NativePluralRules.OTHER, en_US.quantityForInt(0));
- assertEquals(NativePluralRules.OTHER, en_US.quantityForInt(-1));
- assertEquals(NativePluralRules.OTHER, en_US.quantityForInt(-2));
-
- NativePluralRules ar = NativePluralRules.forLocale(new Locale("ar"));
- assertEquals(NativePluralRules.ZERO, ar.quantityForInt(0));
- assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-1)); // Not ONE.
- assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-2)); // Not TWO.
- assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-3)); // Not FEW.
- assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-11)); // Not MANY.
- assertEquals(NativePluralRules.OTHER, ar.quantityForInt(-100));
- }
-
- public void testEnglish() throws Exception {
- NativePluralRules npr = NativePluralRules.forLocale(new Locale("en", "US"));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(0));
- assertEquals(NativePluralRules.ONE, npr.quantityForInt(1));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(2));
- }
-
- public void testCzech() throws Exception {
- NativePluralRules npr = NativePluralRules.forLocale(new Locale("cs", "CZ"));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(0));
- assertEquals(NativePluralRules.ONE, npr.quantityForInt(1));
- assertEquals(NativePluralRules.FEW, npr.quantityForInt(2));
- assertEquals(NativePluralRules.FEW, npr.quantityForInt(3));
- assertEquals(NativePluralRules.FEW, npr.quantityForInt(4));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(5));
- }
-
- public void testArabic() throws Exception {
- NativePluralRules npr = NativePluralRules.forLocale(new Locale("ar"));
- assertEquals(NativePluralRules.ZERO, npr.quantityForInt(0));
- assertEquals(NativePluralRules.ONE, npr.quantityForInt(1));
- assertEquals(NativePluralRules.TWO, npr.quantityForInt(2));
- for (int i = 3; i <= 10; ++i) {
- assertEquals(NativePluralRules.FEW, npr.quantityForInt(i));
- }
- assertEquals(NativePluralRules.MANY, npr.quantityForInt(11));
- assertEquals(NativePluralRules.MANY, npr.quantityForInt(99));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(100));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(101));
- assertEquals(NativePluralRules.OTHER, npr.quantityForInt(102));
- assertEquals(NativePluralRules.FEW, npr.quantityForInt(103));
- assertEquals(NativePluralRules.MANY, npr.quantityForInt(111));
- }
-
- public void testHebrew() throws Exception {
- // java.util.Locale will translate "he" to the deprecated "iw".
- NativePluralRules he = NativePluralRules.forLocale(new Locale("he"));
- assertEquals(NativePluralRules.ONE, he.quantityForInt(1));
- assertEquals(NativePluralRules.TWO, he.quantityForInt(2));
- assertEquals(NativePluralRules.OTHER, he.quantityForInt(3));
- assertEquals(NativePluralRules.OTHER, he.quantityForInt(10));
- }
-}
-
diff --git a/luni/src/test/java/libcore/icu/TransliteratorTest.java b/luni/src/test/java/libcore/icu/TransliteratorTest.java
index 9ced2de..626d951 100644
--- a/luni/src/test/java/libcore/icu/TransliteratorTest.java
+++ b/luni/src/test/java/libcore/icu/TransliteratorTest.java
@@ -16,18 +16,24 @@
package libcore.icu;
+import android.icu.text.Transliterator;
+
+import java.util.Enumeration;
+
public class TransliteratorTest extends junit.framework.TestCase {
public void testAll() throws Exception {
- for (String id : Transliterator.getAvailableIDs()) {
+ Enumeration<String> ids = Transliterator.getAvailableIDs();
+ while (ids.hasMoreElements()) {
+ String id = ids.nextElement();
System.err.println(id);
- Transliterator t = new Transliterator(id);
+ Transliterator t = Transliterator.getInstance(id);
t.transliterate("hello");
}
}
public void test_Unknown() throws Exception {
try {
- Transliterator t = new Transliterator("Unknown");
+ Transliterator t = Transliterator.getInstance("Unknown");
fail();
} catch (RuntimeException expected) {
}
@@ -35,29 +41,20 @@
public void test_null_id() throws Exception {
try {
- Transliterator t = new Transliterator(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_null_string() throws Exception {
- try {
- Transliterator t = new Transliterator("Any-Upper");
- t.transliterate(null);
+ Transliterator t = Transliterator.getInstance(null);
fail();
} catch (NullPointerException expected) {
}
}
public void test_Any_Upper() throws Exception {
- Transliterator t = new Transliterator("Any-Upper");
+ Transliterator t = Transliterator.getInstance("Any-Upper");
assertEquals("HELLO WORLD!", t.transliterate("HeLlO WoRlD!"));
assertEquals("STRASSE", t.transliterate("Straße"));
}
public void test_Any_Lower() throws Exception {
- Transliterator t = new Transliterator("Any-Lower");
+ Transliterator t = Transliterator.getInstance("Any-Lower");
assertEquals("hello world!", t.transliterate("HeLlO WoRlD!"));
}
@@ -65,34 +62,34 @@
String greek = "Καλημέρα κόσμε!";
// Transliterate Greek to Latin, then to plain ASCII.
- Transliterator t = new Transliterator("Greek-Latin");
+ Transliterator t = Transliterator.getInstance("Greek-Latin");
String latin = t.transliterate(greek);
- t = new Transliterator("Latin-Ascii");
+ t = Transliterator.getInstance("Latin-Ascii");
String ascii = t.transliterate(latin);
assertEquals("Kalēméra kósme!", latin);
assertEquals("Kalemera kosme!", ascii);
// Use alternative transliteration variants.
- t = new Transliterator("Greek-Latin/BGN");
+ t = Transliterator.getInstance("Greek-Latin/BGN");
assertEquals("Kaliméra kósme!", t.transliterate(greek));
- t = new Transliterator("Greek-Latin/UNGEGN");
+ t = Transliterator.getInstance("Greek-Latin/UNGEGN");
assertEquals("Kali̱méra kósme!",t.transliterate(greek));
}
public void test_Han_Latin() throws Exception {
- Transliterator t = new Transliterator("Han-Latin");
+ Transliterator t = Transliterator.getInstance("Han-Latin");
assertEquals("hàn zì/hàn zì", t.transliterate("汉字/漢字"));
assertEquals("chén", t.transliterate("\u6c88"));
assertEquals("shěn", t.transliterate("\u700b"));
assertEquals("jiǎ", t.transliterate("\u8d3e"));
- t = new Transliterator("Han-Latin/Names");
+ t = Transliterator.getInstance("Han-Latin/Names");
assertEquals("shěn", t.transliterate("\u6c88"));
assertEquals("shěn", t.transliterate("\u700b"));
assertEquals("jiǎ", t.transliterate("\u8d3e"));
- t = new Transliterator("Han-Latin/Names; Latin-Ascii; Any-Upper");
+ t = Transliterator.getInstance("Han-Latin/Names; Latin-Ascii; Any-Upper");
assertEquals("SHEN", t.transliterate("\u6c88"));
assertEquals("SHEN", t.transliterate("\u700b"));
assertEquals("JIA", t.transliterate("\u8d3e"));
diff --git a/luni/src/test/java/libcore/io/OsTest.java b/luni/src/test/java/libcore/io/OsTest.java
index e648e8a..1dcc3c6 100644
--- a/luni/src/test/java/libcore/io/OsTest.java
+++ b/luni/src/test/java/libcore/io/OsTest.java
@@ -18,9 +18,12 @@
import android.system.ErrnoException;
import android.system.NetlinkSocketAddress;
+import android.system.OsConstants;
import android.system.PacketSocketAddress;
import android.system.StructTimeval;
import android.system.StructUcred;
+import android.system.UnixSocketAddress;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -29,10 +32,8 @@
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.net.InetUnixAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
-import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
@@ -69,19 +70,25 @@
public void testUnixDomainSockets_in_file_system() throws Exception {
String path = System.getProperty("java.io.tmpdir") + "/test_unix_socket";
new File(path).delete();
- checkUnixDomainSocket(new InetUnixAddress(path), false);
+ checkUnixDomainSocket(UnixSocketAddress.createFileSystem(path), false);
}
public void testUnixDomainSocket_abstract_name() throws Exception {
// Linux treats a sun_path starting with a NUL byte as an abstract name. See unix(7).
- byte[] path = "/abstract_name_unix_socket".getBytes("UTF-8");
- path[0] = 0;
- checkUnixDomainSocket(new InetUnixAddress(path), true);
+ checkUnixDomainSocket(UnixSocketAddress.createAbstract("/abstract_name_unix_socket"), true);
}
- private void checkUnixDomainSocket(final InetUnixAddress address, final boolean isAbstract) throws Exception {
+ public void testUnixDomainSocket_unnamed() throws Exception {
+ final FileDescriptor fd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
+ // unix(7) says an unbound socket is unnamed.
+ checkNoSockName(fd);
+ Libcore.os.close(fd);
+ }
+
+ private void checkUnixDomainSocket(final UnixSocketAddress address, final boolean isAbstract)
+ throws Exception {
final FileDescriptor serverFd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
- Libcore.os.bind(serverFd, address, 0);
+ Libcore.os.bind(serverFd, address);
Libcore.os.listen(serverFd, 5);
checkSockName(serverFd, isAbstract, address);
@@ -89,7 +96,7 @@
Thread server = new Thread(new Runnable() {
public void run() {
try {
- InetSocketAddress peerAddress = new InetSocketAddress();
+ UnixSocketAddress peerAddress = UnixSocketAddress.createUnnamed();
FileDescriptor clientFd = Libcore.os.accept(serverFd, peerAddress);
checkSockName(clientFd, isAbstract, address);
checkNoName(peerAddress);
@@ -118,7 +125,7 @@
FileDescriptor clientFd = Libcore.os.socket(AF_UNIX, SOCK_STREAM, 0);
- Libcore.os.connect(clientFd, address, 0);
+ Libcore.os.connect(clientFd, address);
checkNoSockName(clientFd);
String string = "hello, world!";
@@ -134,26 +141,25 @@
Libcore.os.close(clientFd);
}
- private void checkSockName(FileDescriptor fd, boolean isAbstract, InetAddress address) throws Exception {
- InetSocketAddress isa = (InetSocketAddress) Libcore.os.getsockname(fd);
+ private static void checkSockName(FileDescriptor fd, boolean isAbstract,
+ UnixSocketAddress address) throws Exception {
+ UnixSocketAddress isa = (UnixSocketAddress) Libcore.os.getsockname(fd);
+ assertEquals(address, isa);
if (isAbstract) {
- checkNoName(isa);
- } else {
- assertEquals(address, isa.getAddress());
+ assertEquals(0, isa.getSunPath()[0]);
}
}
- private void checkNoName(SocketAddress sa) {
- InetSocketAddress isa = (InetSocketAddress) sa;
- assertEquals(0, isa.getAddress().getAddress().length);
+ private void checkNoName(UnixSocketAddress usa) {
+ assertEquals(0, usa.getSunPath().length);
}
private void checkNoPeerName(FileDescriptor fd) throws Exception {
- checkNoName(Libcore.os.getpeername(fd));
+ checkNoName((UnixSocketAddress) Libcore.os.getpeername(fd));
}
private void checkNoSockName(FileDescriptor fd) throws Exception {
- checkNoName(Libcore.os.getsockname(fd));
+ checkNoName((UnixSocketAddress) Libcore.os.getsockname(fd));
}
public void test_strsignal() throws Exception {
@@ -219,7 +225,7 @@
}
static void checkByteBufferPositions_sendto_recvfrom(
- int family, InetAddress loopback) throws Exception {
+ int family, InetAddress loopback) throws Exception {
final FileDescriptor serverFd = Libcore.os.socket(family, SOCK_STREAM, 0);
Libcore.os.bind(serverFd, loopback, 0);
Libcore.os.listen(serverFd, 5);
@@ -252,13 +258,13 @@
}
});
-
server.start();
FileDescriptor clientFd = Libcore.os.socket(family, SOCK_STREAM, 0);
Libcore.os.connect(clientFd, address.getAddress(), address.getPort());
- final byte[] bytes = "good bye, cruel black hole with fancy distortion".getBytes(StandardCharsets.US_ASCII);
+ final byte[] bytes = "good bye, cruel black hole with fancy distortion"
+ .getBytes(StandardCharsets.US_ASCII);
assertTrue(bytes.length > 24);
ByteBuffer input = ByteBuffer.wrap(bytes);
@@ -340,11 +346,11 @@
}
public void test_sendtoSocketAddress_af_inet() throws Exception {
- checkSendToSocketAddress(AF_INET, InetAddress.getByName("127.0.0.1"));
+ checkSendToSocketAddress(AF_INET, InetAddress.getByName("127.0.0.1"));
}
public void test_sendtoSocketAddress_af_inet6() throws Exception {
- checkSendToSocketAddress(AF_INET6, InetAddress.getByName("::1"));
+ checkSendToSocketAddress(AF_INET6, InetAddress.getByName("::1"));
}
public void test_socketFamilies() throws Exception {
@@ -372,11 +378,11 @@
private static void assertArrayEquals(byte[] expected, byte[] actual) {
assertTrue("Expected=" + Arrays.toString(expected) + ", actual=" + Arrays.toString(actual),
- Arrays.equals(expected, actual));
+ Arrays.equals(expected, actual));
}
private static void checkSocketPing(FileDescriptor fd, InetAddress to, byte[] packet,
- byte type, byte responseType, boolean useSendto) throws Exception {
+ byte type, byte responseType, boolean useSendto) throws Exception {
int len = packet.length;
packet[0] = type;
if (useSendto) {
@@ -406,8 +412,8 @@
final byte ICMP_ECHO = 8, ICMP_ECHOREPLY = 0;
final byte ICMPV6_ECHO_REQUEST = (byte) 128, ICMPV6_ECHO_REPLY = (byte) 129;
final byte[] packet = ("\000\000\000\000" + // ICMP type, code.
- "\000\000\000\003" + // ICMP ID (== port), sequence number.
- "Hello myself").getBytes(StandardCharsets.US_ASCII);
+ "\000\000\000\003" + // ICMP ID (== port), sequence number.
+ "Hello myself").getBytes(StandardCharsets.US_ASCII);
FileDescriptor fd = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
InetAddress ipv6Loopback = InetAddress.getByName("::1");
@@ -419,4 +425,90 @@
checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, true);
checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, false);
}
+
+ public void test_Ipv4Fallback() throws Exception {
+ // This number of iterations gives a ~60% chance of creating the conditions that caused
+ // http://b/23088314 without making test times too long. On a hammerhead running MRZ37C using
+ // vogar, this test takes about 4s.
+ final int ITERATIONS = 10000;
+ for (int i = 0; i < ITERATIONS; i++) {
+ FileDescriptor mUdpSock = Libcore.os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ try {
+ Libcore.os.bind(mUdpSock, Inet4Address.ANY, 0);
+ } catch(ErrnoException e) {
+ fail("ErrnoException after " + i + " iterations: " + e);
+ } finally {
+ Libcore.os.close(mUdpSock);
+ }
+ }
+ }
+
+ public void test_unlink() throws Exception {
+ File f = File.createTempFile("OsTest", "tst");
+ assertTrue(f.exists());
+ Libcore.os.unlink(f.getAbsolutePath());
+ assertFalse(f.exists());
+
+ try {
+ Libcore.os.unlink(f.getAbsolutePath());
+ fail();
+ } catch (ErrnoException e) {
+ assertEquals(OsConstants.ENOENT, e.errno);
+ }
+ }
+
+ public void test_xattr() throws Exception {
+ final String NAME_TEST = "user.meow";
+
+ final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
+ final byte[] VALUE_PIE = "pie".getBytes(StandardCharsets.UTF_8);
+
+ File file = File.createTempFile("xattr", "test");
+ String path = file.getAbsolutePath();
+
+ byte[] tmp = new byte[1024];
+ try {
+ try {
+ Libcore.os.getxattr(path, NAME_TEST, tmp);
+ fail("Expected ENODATA");
+ } catch (ErrnoException e) {
+ assertEquals(OsConstants.ENODATA, e.errno);
+ }
+
+ Libcore.os.setxattr(path, NAME_TEST, VALUE_CAKE, OsConstants.XATTR_CREATE);
+ assertEquals(VALUE_CAKE.length, Libcore.os.getxattr(path, NAME_TEST, tmp));
+ assertStartsWith(VALUE_CAKE, tmp);
+
+ try {
+ Libcore.os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_CREATE);
+ fail("Expected EEXIST");
+ } catch (ErrnoException e) {
+ assertEquals(OsConstants.EEXIST, e.errno);
+ }
+
+ Libcore.os.setxattr(path, NAME_TEST, VALUE_PIE, OsConstants.XATTR_REPLACE);
+ assertEquals(VALUE_PIE.length, Libcore.os.getxattr(path, NAME_TEST, tmp));
+ assertStartsWith(VALUE_PIE, tmp);
+
+ Libcore.os.removexattr(path, NAME_TEST);
+ try {
+ Libcore.os.getxattr(path, NAME_TEST, tmp);
+ fail("Expected ENODATA");
+ } catch (ErrnoException e) {
+ assertEquals(OsConstants.ENODATA, e.errno);
+ }
+
+ } finally {
+ file.delete();
+ }
+ }
+
+ private static void assertStartsWith(byte[] expectedContents, byte[] container) {
+ for (int i = 0; i < expectedContents.length; i++) {
+ if (expectedContents[i] != container[i]) {
+ fail("Expected " + Arrays.toString(expectedContents) + " but found "
+ + Arrays.toString(expectedContents));
+ }
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/io/SerializationTest.java b/luni/src/test/java/libcore/java/io/SerializationTest.java
index 32bc402..03e7d94 100644
--- a/luni/src/test/java/libcore/java/io/SerializationTest.java
+++ b/luni/src/test/java/libcore/java/io/SerializationTest.java
@@ -49,7 +49,9 @@
static class FieldMadeTransient implements Serializable {
private static final long serialVersionUID = 0L;
+ @SuppressWarnings("unused")
private transient int transientInt;
+ @SuppressWarnings("unused")
private int nonTransientInt;
}
@@ -64,7 +66,7 @@
+ "374244669656c644d6164655374617469630000000000000000020001490009737461746963496e7"
+ "47870000022b8";
FieldMadeStatic deserialized = (FieldMadeStatic) SerializationTester.deserializeHex(s);
- // The field data is simply ignored if it is static.
+ // The field data must be ignored if it is static.
assertEquals(9999, deserialized.staticInt);
}
@@ -74,73 +76,101 @@
private static int staticInt = 9999;
}
+ public static boolean serializableContainer1InitializedFlag = false;
+ public static boolean unserializable1InitializedFlag = false;
+
+ public static class Unserializable1 {
+ static {
+ SerializationTest.unserializable1InitializedFlag = true;
+ }
+ }
+
+ static class SerializableContainer1 implements Serializable {
+ private static final long serialVersionUID = 0L;
+ private Unserializable1 unserializable = null;
+
+ static {
+ serializableContainer1InitializedFlag = true;
+ }
+ }
+
// We can serialize an object that has an unserializable field providing it is null.
public void testDeserializeNullUnserializableField() throws Exception {
// This was created by creating a new SerializableContainer and not setting the
// unserializable field. A canned serialized form is used so we can tell if the static
// initializers were executed during deserialization.
- // SerializationTester.serializeHex(new SerializableContainer());
- String s = "aced0005737200376c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6e54657"
- + "3742453657269616c697a61626c65436f6e7461696e657200000000000000000200014c000e756e7"
- + "3657269616c697a61626c657400334c6c6962636f72652f6a6176612f696f2f53657269616c697a6"
- + "174696f6e546573742457617353657269616c697a61626c653b787070";
+ // SerializationTester.serializeHex(new SerializableContainer1());
+ String s = "aced0005737200386c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6e54657"
+ + "3742453657269616c697a61626c65436f6e7461696e65723100000000000000000200014c000e7"
+ + "56e73657269616c697a61626c657400124c6a6176612f6c616e672f4f626a6563743b787070";
- serializableContainerInitializedFlag = false;
- wasSerializableInitializedFlag = false;
+ assertFalse(serializableContainer1InitializedFlag);
+ assertFalse(unserializable1InitializedFlag);
- SerializableContainer sc = (SerializableContainer) SerializationTester.deserializeHex(s);
+ SerializableContainer1 sc = (SerializableContainer1) SerializationTester.deserializeHex(s);
assertNull(sc.unserializable);
// Confirm the container was initialized, but the class for the null field was not.
- assertTrue(serializableContainerInitializedFlag);
- assertFalse(wasSerializableInitializedFlag);
+ assertTrue(serializableContainer1InitializedFlag);
+ assertFalse(unserializable1InitializedFlag);
}
- public static boolean serializableContainerInitializedFlag = false;
+ static class Unserializable2 {
+ }
- static class SerializableContainer implements Serializable {
+ static class HasUnserializableField implements Serializable {
private static final long serialVersionUID = 0L;
- private Object unserializable = null;
-
- static {
- serializableContainerInitializedFlag = true;
- }
+ @SuppressWarnings("unused") // Required to make objects unserializable.
+ private Unserializable2 unserializable = new Unserializable2();
}
// We must not serialize an object that has a non-null unserializable field.
public void testSerializeUnserializableField() throws Exception {
- SerializableContainer sc = new SerializableContainer();
- sc.unserializable = new WasSerializable();
+ HasUnserializableField uf = new HasUnserializableField();
try {
- SerializationTester.serializeHex(sc);
+ SerializationTester.serializeHex(uf);
fail();
} catch (NotSerializableException expected) {
}
}
+ public static boolean serializableContainer2InitializedFlag = false;
+
+ @SuppressWarnings("unused") // Required for deserialization test
+ static class SerializableContainer2 implements Serializable {
+ private static final long serialVersionUID = 0L;
+ private WasSerializable unserializable = null;
+
+ static {
+ serializableContainer2InitializedFlag = true;
+ }
+ }
+
// It must not be possible to deserialize an object if a field is no longer serializable.
public void testDeserializeUnserializableField() throws Exception {
- // This was generated by creating a SerializableContainer and setting the unserializable
+ // This was generated by creating a SerializableContainer2 and setting the unserializable
// field to a WasSerializable when it was still Serializable. A canned serialized form is
// used so we can tell if the static initializers were executed during deserialization.
- // SerializableContainer sc = new SerializableContainer();
+ // SerializableContainer2 sc = new SerializableContainer2();
// sc.unserializable = new WasSerializable();
// SerializationTester.serializeHex(sc);
- String s = "aced0005737200376c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6e54657"
- + "3742453657269616c697a61626c65436f6e7461696e657200000000000000000200014c000e756e7"
- + "3657269616c697a61626c657400124c6a6176612f6c616e672f4f626a6563743b7870737200316c6"
- + "962636f72652e6a6176612e696f2e53657269616c697a6174696f6e5465737424576173536572696"
- + "16c697a61626c65000000000000000002000149000169787000000000";
+ String s = "aced0005737200386c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6e54657"
+ + "3742453657269616c697a61626c65436f6e7461696e65723200000000000000000200014c000e7"
+ + "56e73657269616c697a61626c657400334c6c6962636f72652f6a6176612f696f2f53657269616"
+ + "c697a6174696f6e546573742457617353657269616c697a61626c653b7870737200316c6962636"
+ + "f72652e6a6176612e696f2e53657269616c697a6174696f6e546573742457617353657269616c6"
+ + "97a61626c65000000000000000002000149000169787000000000";
- serializableContainerInitializedFlag = false;
- wasSerializableInitializedFlag = false;
+ assertFalse(serializableContainer2InitializedFlag);
+ assertFalse(wasSerializableInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
} catch (InvalidClassException expected) {
}
- // Confirm neither the container nor the contained class was initialized.
- assertFalse(serializableContainerInitializedFlag);
+ // The container class will be initialized to establish the serialVersionUID.
+ assertTrue(serializableContainer2InitializedFlag);
+ // Confirm the contained class was initialized.
assertFalse(wasSerializableInitializedFlag);
}
@@ -196,7 +226,7 @@
+ "e546573742457617353657269616c697a61626c65000000000000000002000149000169787000000"
+ "000";
- wasSerializableInitializedFlag = false;
+ assertFalse(wasSerializableInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
@@ -239,7 +269,7 @@
final String s = "aced0005737200336c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6"
+ "e546573742457617345787465726e616c697a61626c6500000000000000000c0000787078";
- wasExternalizableInitializedFlag = false;
+ assertFalse(wasExternalizableInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
@@ -275,7 +305,7 @@
+ "e5465737424576173456e756d00000000000000001200007872000e6a6176612e6c616e672e456e7"
+ "56d0000000000000000120000787074000556414c5545";
- wasEnumInitializedFlag = false;
+ assertFalse(wasEnumInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
@@ -309,7 +339,7 @@
final String s = "aced00057372002b6c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6"
+ "e54657374245761734f626a656374000000000000000002000149000169787000000000";
- wasObjectInitializedFlag = false;
+ assertFalse(wasObjectInitializedFlag);
try {
SerializationTester.deserializeHex(s);
fail();
diff --git a/luni/src/test/java/libcore/java/lang/OldAndroidMonitorTest.java b/luni/src/test/java/libcore/java/lang/OldAndroidMonitorTest.java
index 4760c6d..8ef507a 100755
--- a/luni/src/test/java/libcore/java/lang/OldAndroidMonitorTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldAndroidMonitorTest.java
@@ -18,6 +18,8 @@
import junit.framework.TestCase;
+import java.util.concurrent.CountDownLatch;
+
public class OldAndroidMonitorTest extends TestCase {
public void testWaitArgumentsTest() throws Exception {
@@ -102,363 +104,69 @@
}
}
- private class Interrupter extends Thread {
- private final Waiter waiter;
+ /**
+ * A thread that blocks forever on {@code wait()} until it's interrupted.
+ */
+ static class Waiter extends Thread {
+ private final Object lock;
+ private final CountDownLatch cdl;
+ private boolean wasInterrupted;
- Interrupter(String name, Waiter waiter) {
- super(name);
- this.waiter = waiter;
- }
-
- public void run() {
- try {
- run_inner();
- } catch (Throwable t) {
- OldAndroidMonitorTest.errorException = t;
- OldAndroidMonitorTest.testThread.interrupt();
- }
- }
-
- private void run_inner() {
- // System.out.println("InterruptTest: starting waiter");
- waiter.start();
-
- try {
- Thread.currentThread().sleep(500);
- } catch (InterruptedException ex) {
- throw new RuntimeException("Test sleep interrupted.", ex);
- }
-
- /* Waiter is spinning, and its monitor should still be thin.
- */
- // System.out.println("Test interrupting waiter");
- waiter.interrupt();
- waiter.spin = false;
-
- for (int i = 0; i < 3; i++) {
- /* Wait for the waiter to start waiting.
- */
- synchronized (waiter.interrupterLock) {
- try {
- waiter.interrupterLock.wait();
- } catch (InterruptedException ex) {
- throw new RuntimeException("Test wait interrupted.", ex);
- }
- }
-
- /* Before interrupting, grab the waiter lock, which
- * guarantees that the waiter is already sitting in wait().
- */
- synchronized (waiter) {
- //System.out.println("Test interrupting waiter (" + i + ")");
- waiter.interrupt();
- }
- }
-
- // System.out.println("Test waiting for waiter to die.");
- try {
- waiter.join();
- } catch (InterruptedException ex) {
- throw new RuntimeException("Test join interrupted.", ex);
- }
- // System.out.println("InterruptTest done.");
- }
+ public Waiter(Object lock, CountDownLatch cdl) {
+ this.lock = lock;
+ this.cdl = cdl;
+ wasInterrupted = false;
}
- private class Waiter extends Thread {
- Object interrupterLock = new Object();
- volatile boolean spin = true;
-
- Waiter(String name) {
- super(name);
- }
-
- public void run() {
- try {
- run_inner();
- } catch (Throwable t) {
- OldAndroidMonitorTest.errorException = t;
- OldAndroidMonitorTest.testThread.interrupt();
- }
- }
-
- void run_inner() {
- // System.out.println("Waiter spinning");
- while (spin) {
- // We're going to get interrupted while we spin.
- }
-
- if (interrupted()) {
- // System.out.println("Waiter done spinning; interrupted.");
- } else {
- throw new RuntimeException("Thread not interrupted " +
- "during spin");
- }
-
- synchronized (this) {
- boolean sawEx = false;
-
- try {
- synchronized (interrupterLock) {
- interrupterLock.notify();
- }
- // System.out.println("Waiter calling wait()");
- this.wait();
- } catch (InterruptedException ex) {
- sawEx = true;
- // System.out.println("wait(): Waiter caught " + ex);
- }
- // System.out.println("wait() finished");
-
- if (!sawEx) {
- throw new RuntimeException("Thread not interrupted " +
- "during wait()");
- }
- }
- synchronized (this) {
- boolean sawEx = false;
-
- try {
- synchronized (interrupterLock) {
- interrupterLock.notify();
- }
- // System.out.println("Waiter calling wait(1000)");
- this.wait(1000);
- } catch (InterruptedException ex) {
- sawEx = true;
- // System.out.println("wait(1000): Waiter caught " + ex);
- }
- // System.out.println("wait(1000) finished");
-
- if (!sawEx) {
- throw new RuntimeException("Thread not interrupted " +
- "during wait(1000)");
- }
- }
- synchronized (this) {
- boolean sawEx = false;
-
- try {
- synchronized (interrupterLock) {
- interrupterLock.notify();
- }
- // System.out.println("Waiter calling wait(1000, 5000)");
- this.wait(1000, 5000);
- } catch (InterruptedException ex) {
- sawEx = true;
- // System.out.println("wait(1000, 5000): Waiter caught " + ex);
- }
- // System.out.println("wait(1000, 5000) finished");
-
- if (!sawEx) {
- throw new RuntimeException("Thread not interrupted " +
- "during wait(1000, 5000)");
- }
- }
-
- // System.out.println("Waiter returning");
- }
- }
-
- private static Throwable errorException;
- private static Thread testThread;
-
- // TODO: Flaky test. Add back MediumTest annotation once fixed
- public void testInterruptTest() throws Exception {
-
-
- testThread = Thread.currentThread();
- errorException = null;
-
- Waiter waiter = new Waiter("InterruptTest Waiter");
- Interrupter interrupter =
- new Interrupter("InterruptTest Interrupter", waiter);
- interrupter.start();
-
- try {
- interrupter.join();
- waiter.join();
- } catch (InterruptedException ex) {
- throw new RuntimeException("Test join interrupted.", ex);
- }
-
- if (errorException != null) {
- throw new RuntimeException("InterruptTest failed",
- errorException);
- }
-
-
-
-
- }
-
- private static void deepWait(int depth, Object lock) {
- synchronized (lock) {
- if (depth > 0) {
- deepWait(depth - 1, lock);
- } else {
- String threadName = Thread.currentThread().getName();
- try {
- // System.out.println(threadName + " waiting");
- lock.wait();
- // System.out.println(threadName + " done waiting");
- } catch (InterruptedException ex) {
- // System.out.println(threadName + " interrupted.");
- }
- }
- }
- }
-
- private class Worker extends Thread {
- Object lock;
- int id;
-
- Worker(int id, Object lock) {
- super("Worker(" + id + ")");
- this.id = id;
- this.lock = lock;
- }
-
- public void run() {
- int iterations = 0;
-
- while (OldAndroidMonitorTest.running) {
- OldAndroidMonitorTest.deepWait(id, lock);
- iterations++;
- }
- // System.out.println(getName() + " done after " + iterations + " iterations.");
- }
- }
-
- private static Object commonLock = new Object();
- private static Boolean running = false;
-
-
- public void testNestedMonitors() throws Exception {
- final int NUM_WORKERS = 5;
-
- Worker w[] = new Worker[NUM_WORKERS];
- int i;
-
- for (i = 0; i < NUM_WORKERS; i++) {
- w[i] = new Worker(i * 2 - 1, new Object());
- }
-
- running = true;
-
- // System.out.println("NestedMonitors: starting workers");
- for (i = 0; i < NUM_WORKERS; i++) {
- w[i].start();
- }
-
- try {
- Thread.currentThread().sleep(1000);
- } catch (InterruptedException ex) {
- // System.out.println("Test sleep interrupted.");
- }
-
- for (i = 0; i < 100; i++) {
- for (int j = 0; j < NUM_WORKERS; j++) {
- synchronized (w[j].lock) {
- w[j].lock.notify();
- }
- }
- }
-
- // System.out.println("NesterMonitors: stopping workers");
- running = false;
- for (i = 0; i < NUM_WORKERS; i++) {
- synchronized (w[i].lock) {
- w[i].lock.notifyAll();
- }
- }
- }
-
- private static class CompareAndExchange extends Thread {
- static Object toggleLock = null;
- static int toggle = -1;
- static Boolean running = false;
-
+ @Override
public void run() {
- toggleLock = new Object();
- toggle = -1;
-
- Worker w1 = new Worker(0, 1);
- Worker w2 = new Worker(2, 3);
- Worker w3 = new Worker(4, 5);
- Worker w4 = new Worker(6, 7);
-
- running = true;
-
- // System.out.println("CompareAndExchange: starting workers");
-
- w1.start();
- w2.start();
- w3.start();
- w4.start();
-
- try {
- this.sleep(10000);
- } catch (InterruptedException ex) {
- // System.out.println(getName() + " interrupted.");
- }
-
- // System.out.println("MonitorTest: stopping workers");
- running = false;
-
- toggleLock = null;
- }
-
- class Worker extends Thread {
- int i1;
- int i2;
-
- Worker(int i1, int i2) {
- super("Worker(" + i1 + ", " + i2 + ")");
- this.i1 = i1;
- this.i2 = i2;
- }
-
- public void run() {
- int iterations = 0;
-
- /* Latch this because run() may set the static field to
- * null at some point.
- */
- Object toggleLock = CompareAndExchange.toggleLock;
-
- // System.out.println(getName() + " running");
+ synchronized (lock) {
try {
- while (CompareAndExchange.running) {
- synchronized (toggleLock) {
- int test;
- int check;
-
- if (CompareAndExchange.toggle == i1) {
- this.sleep(5 + i2);
- CompareAndExchange.toggle = test = i2;
- } else {
- this.sleep(5 + i1);
- CompareAndExchange.toggle = test = i1;
- }
- if ((check = CompareAndExchange.toggle) != test) {
-// System.out.println("Worker(" + i1 + ", " +
-// i2 + ") " + "test " + test +
-// " != toggle " + check);
- throw new RuntimeException(
- "locked value changed");
- }
- }
-
- iterations++;
+ cdl.countDown();
+ while (true) {
+ lock.wait();
}
} catch (InterruptedException ex) {
- // System.out.println(getName() + " interrupted.");
+ wasInterrupted = true;
}
-
-// System.out.println(getName() + " done after " +
-// iterations + " iterations.");
}
}
+
+ public boolean wasInterrupted() {
+ synchronized (lock) {
+ return wasInterrupted;
+ }
+ }
+ }
+
+ public void testInterrupt() throws Exception {
+ final Object lock = new Object();
+ final CountDownLatch cdl = new CountDownLatch(1);
+ final Waiter waiter = new Waiter(lock, cdl);
+
+ waiter.start();
+
+ // Wait for the "waiter" to start and acquire |lock| for the first time.
+ try {
+ cdl.await();
+ } catch (InterruptedException ie) {
+ fail();
+ }
+
+ // Interrupt |waiter| after we acquire |lock|. This ensures that |waiter| is
+ // currently blocked on a call to "wait".
+ synchronized (lock) {
+ waiter.interrupt();
+ }
+
+ // Wait for the waiter to complete.
+ try {
+ waiter.join();
+ } catch (InterruptedException ie) {
+ fail();
+ }
+
+ // Assert than an InterruptedException was thrown.
+ assertTrue(waiter.wasInterrupted());
}
}
diff --git a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
index b7c4bc6..116eb3f 100644
--- a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
+++ b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
@@ -22,14 +22,18 @@
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import libcore.io.IoUtils;
public class NetworkInterfaceTest extends TestCase {
// http://code.google.com/p/android/issues/detail?id=13784
+ private final static int ARPHRD_ETHER = 1; // from if_arp.h
public void testIPv6() throws Exception {
NetworkInterface lo = NetworkInterface.getByName("lo");
Set<InetAddress> actual = new HashSet<InetAddress>(Collections.list(lo.getInetAddresses()));
@@ -70,24 +74,31 @@
assertEquals(1, ifAddresses.size());
}
+ public void testInterfaceProperties() throws Exception {
+ for (NetworkInterface nif : Collections.list(NetworkInterface.getNetworkInterfaces())) {
+ assertEquals(nif, NetworkInterface.getByName(nif.getName()));
+ // Skip interfaces that are inactive
+ if (nif.isUp() == false) {
+ continue;
+ }
+ // Ethernet
+ if (isEthernet(nif.getName())) {
+ assertEquals(6, nif.getHardwareAddress().length);
+ for (InterfaceAddress ia : nif.getInterfaceAddresses()) {
+ if (ia.getAddress() instanceof Inet4Address) {
+ assertNotNull(ia.getBroadcast());
+ }
+ }
+ }
+ }
+ }
+
public void testLoopback() throws Exception {
- // We know lo shouldn't have a hardware address or an IPv4 broadcast address.
NetworkInterface lo = NetworkInterface.getByName("lo");
assertNull(lo.getHardwareAddress());
for (InterfaceAddress ia : lo.getInterfaceAddresses()) {
assertNull(ia.getBroadcast());
}
-
- // But eth0, if it exists, should...
- NetworkInterface eth0 = NetworkInterface.getByName("eth0");
- if (eth0 != null) {
- assertEquals(6, eth0.getHardwareAddress().length);
- for (InterfaceAddress ia : eth0.getInterfaceAddresses()) {
- if (ia.getAddress() instanceof Inet4Address) {
- assertNotNull(ia.getBroadcast());
- }
- }
- }
}
public void testDumpAll() throws Exception {
@@ -130,4 +141,14 @@
allIndexes.add(nif.getIndex());
}
}
+
+ // Returns true if interface by name ifName is Ethernet
+ private boolean isEthernet(String ifName) throws Exception {
+ String s = IoUtils.readFileAsString("/sys/class/net/" + ifName + "/type").trim();
+ if (s.startsWith("0x")) {
+ return (Integer.parseInt(s.substring(2), 16) == ARPHRD_ETHER);
+ } else {
+ return (Integer.parseInt(s) == ARPHRD_ETHER);
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/nio/charset/CharsetDecoderTest.java b/luni/src/test/java/libcore/java/nio/charset/CharsetDecoderTest.java
index 4fa6e0c..db2be53 100644
--- a/luni/src/test/java/libcore/java/nio/charset/CharsetDecoderTest.java
+++ b/luni/src/test/java/libcore/java/nio/charset/CharsetDecoderTest.java
@@ -85,7 +85,11 @@
private static byte[] encode(String charsetName, String s) throws Exception {
CharsetEncoder encoder = Charset.forName(charsetName).newEncoder();
- return encoder.encode(CharBuffer.wrap(s)).array();
+ ByteBuffer buf = encoder.encode(CharBuffer.wrap(s));
+ byte[] out = new byte[buf.remaining()];
+ buf.get(out);
+ assertEquals(0, buf.remaining());
+ return out;
}
public void testUtf8BytesSplitAcrossMultipleWrites() throws Exception {
diff --git a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
index 1320a8a..10bb621 100644
--- a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
+++ b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java
@@ -56,13 +56,32 @@
public class KeyPairGeneratorTest extends TestCase {
- public void test_providerCount() {
+ private List<Provider> providers = new ArrayList<Provider>();
+
+ @Override
+ public void setUp() {
Provider[] providers = Security.getProviders();
+ for (Provider p : providers) {
+ // Do not test AndroidKeyStore Provider. It does not accept vanilla public keys for
+ // signature verification. It's OKish not to test here because it's tested by
+ // cts/tests/tests/keystore.
+ if (!p.getName().startsWith("AndroidKeyStore")) {
+ this.providers.add(p);
+ }
+ }
+ }
+
+ @Override
+ public void tearDown() {
+ providers.clear();
+ }
+
+ public void test_providerCount() {
// We expect there to be at least one provider.
- assertTrue(providers.length > 0);
+ assertTrue(providers.size() > 0);
// If this fails remember to add _provider methods below. This test is sharded because it
// takes a long time to execute.
- assertTrue(providers.length < 10);
+ assertTrue(providers.size() < 10);
}
public void test_getInstance_provider0() throws Exception {
@@ -106,14 +125,14 @@
}
private void test_getInstance(int providerIndex) throws Exception {
- Provider[] providers = Security.getProviders();
- if (providerIndex >= providers.length) {
+ if (providerIndex >= providers.size()) {
// Providers can be added by vendors and other tests. We do not
// specify a fixed number and silenty pass if the provider at the
// specified index does not exist.
return;
}
- Provider provider = providers[providerIndex];
+
+ Provider provider = providers.get(providerIndex);
Set<Provider.Service> services = provider.getServices();
for (Provider.Service service : services) {
String type = service.getType();
@@ -121,15 +140,6 @@
continue;
}
String algorithm = service.getAlgorithm();
-
- // Do not test AndroidKeyStore's KeyPairGenerator. It cannot be initialized without
- // providing AndroidKeyStore-specific algorithm parameters.
- // It's OKish not to test AndroidKeyStore's KeyPairGenerator here because it's tested
- // by cts/tests/test/keystore.
- if ("AndroidKeyStore".equals(provider.getName())) {
- continue;
- }
-
AlgorithmParameterSpec params = null;
if ("DH".equals(algorithm)) {
@@ -306,8 +316,6 @@
byte[] encoded = k.getEncoded();
String keyAlgo = k.getAlgorithm();
-
- Provider[] providers = Security.getProviders();
for (Provider p : providers) {
Set<Provider.Service> services = p.getServices();
for (Provider.Service service : services) {
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index f6e3a06..272dc21 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -16,7 +16,14 @@
package libcore.java.security;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import java.lang.reflect.Method;
import java.math.BigInteger;
+import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.KeyFactory;
@@ -29,6 +36,7 @@
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
+import java.security.SignatureSpi;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.ECFieldFp;
@@ -41,8 +49,11 @@
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
@@ -1738,4 +1749,104 @@
result = ecdsaVerify.verify(SIGNATURE);
assertEquals(false, result);
}
+
+ /**
+ * When an instance of a Signature is obtained, it's actually wrapped in an
+ * implementation that makes sure the correct SPI is selected and then calls
+ * through to the underlying SPI. We need to make sure that all methods on
+ * the delegate are wrapped and don't call directly into
+ * {@link SignatureSpi}.
+ */
+ public void testSignatureDelegateOverridesAllMethods() throws Exception {
+ Signature sig = Signature.getInstance("SHA1withRSA");
+
+ /*
+ * Make sure we're dealing with a delegate and not an actual instance of
+ * Signature.
+ */
+ Class<?> sigClass = sig.getClass();
+ assertFalse(sigClass.equals(SignatureSpi.class));
+ assertFalse(sigClass.equals(Signature.class));
+
+ List<String> methodsNotOverridden = new ArrayList<String>();
+
+ for (Method spiMethod : SignatureSpi.class.getDeclaredMethods()) {
+ try {
+ sigClass.getDeclaredMethod(spiMethod.getName(), spiMethod.getParameterTypes());
+ } catch (NoSuchMethodException e) {
+ methodsNotOverridden.add(spiMethod.toString());
+ }
+ }
+
+ assertEquals(Collections.EMPTY_LIST, methodsNotOverridden);
+ }
+
+ public void testGetParameters_IsCalled() throws Exception {
+ Provider provider = spy(new MockableProvider());
+ Provider.Service service = spy(new Provider.Service(provider, "Signature",
+ "FAKEFORGETPARAMETERS", "fake", null, null));
+ MockableSignatureSpi signatureSpi = mock(MockableSignatureSpi.class);
+
+ // Since these are spies, we want to use the doReturn(...) syntax to
+ // avoid calling the real methods.
+ doReturn(service).when(provider).getService(service.getType(), service.getAlgorithm());
+ doReturn(signatureSpi).when(service).newInstance(null);
+
+ Signature sig = Signature.getInstance(service.getAlgorithm(), provider);
+ sig.getParameters();
+ verify(signatureSpi).engineGetParameters();
+ }
+
+ public static class MockableProvider extends Provider {
+ protected MockableProvider() {
+ super("MockableProvider", 1.0, "Used by Mockito");
+ }
+ }
+
+ public static class MockableSignatureSpi extends SignatureSpi {
+ @Override
+ public void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void engineUpdate(byte b) throws SignatureException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public byte[] engineSign() throws SignatureException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void engineSetParameter(String param, Object value) throws InvalidParameterException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object engineGetParameter(String param) throws InvalidParameterException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public AlgorithmParameters engineGetParameters() {
+ throw new UnsupportedOperationException();
+ }
+ }
}
diff --git a/luni/src/test/java/libcore/java/security/cert/FakeOidProvider.java b/luni/src/test/java/libcore/java/security/cert/FakeOidProvider.java
new file mode 100644
index 0000000..3e9183a
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/cert/FakeOidProvider.java
@@ -0,0 +1,69 @@
+package libcore.java.security.cert;
+
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+
+public class FakeOidProvider extends Provider {
+ /**
+ * Used for testing some effects of algorithm OID mapping. We have to be
+ * slightly careful of the OID we pick here: the first number has to be 0,
+ * 1, or 2, and the second number has to be less than 39.
+ */
+ public static final String SIGALG_OID = "1.2.34359737229.1.1.5";
+
+ /**
+ * Used for testing some effects of algorithm OID mapping.
+ */
+ public static final String SIGALG_OID_NAME = "FAKEwithFAKE";
+
+ public static final String PROVIDER_NAME = "FakeOidProvider";
+
+ protected FakeOidProvider() {
+ super(PROVIDER_NAME, 1.0, "Fake OID Provider for Tests");
+
+ put("Signature." + SIGALG_OID, FakeOidSignature.class.getName());
+ }
+
+ public static class FakeOidSignature extends SignatureSpi {
+ @Override
+ protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+ }
+
+ @Override
+ protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+ }
+
+ @Override
+ protected void engineUpdate(byte b) throws SignatureException {
+ }
+
+ @Override
+ protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {
+ }
+
+ @Override
+ protected byte[] engineSign() throws SignatureException {
+ return null;
+ }
+
+ @Override
+ protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ return true;
+ }
+
+ @Override
+ protected void engineSetParameter(String param, Object value)
+ throws InvalidParameterException {
+ }
+
+ @Override
+ protected Object engineGetParameter(String param) throws InvalidParameterException {
+ return null;
+ }
+ }
+}
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
index c35f8e6..5ddbed3 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
@@ -16,6 +16,8 @@
package libcore.java.security.cert;
+import org.apache.harmony.security.utils.AlgNameMapper;
+
import tests.support.resource.Support_Resources;
import java.io.BufferedInputStream;
@@ -294,6 +296,8 @@
generateCertificates_PKCS7_PEM_TrailingData(f);
generateCertificates_PKCS7_DER_TrailingData(f);
test_Serialization(f);
+ test_UnknownUnmappedKeyOID(f);
+ test_UnknownMappedKeyOID(f);
} catch (Throwable e) {
out.append("Error encountered checking " + p.getName() + "\n");
e.printStackTrace(out);
@@ -1174,7 +1178,7 @@
Collection<? extends X509Certificate> certs = (Collection<? extends X509Certificate>)
f.generateCertificates(bais);
if (StandardNames.IS_RI) {
- fail("RI fails on this test.");
+ return;
}
} catch (CertificateParsingException e) {
if (StandardNames.IS_RI) {
@@ -1204,7 +1208,7 @@
Collection<? extends X509Certificate> certs = (Collection<? extends X509Certificate>)
f.generateCertificates(bais);
if (StandardNames.IS_RI) {
- fail("RI fails on this test.");
+ return;
}
} catch (CertificateParsingException e) {
if (StandardNames.IS_RI) {
@@ -1249,12 +1253,7 @@
Collection<? extends X509Certificate> certs = (Collection<? extends X509Certificate>)
f.generateCertificates(bais);
- // RI is broken
- if (StandardNames.IS_RI) {
- assertEquals(0, bais.available());
- } else {
- assertEquals(4096, bais.available());
- }
+ assertEquals(4096, bais.available());
}
private void test_Serialization(CertificateFactory f) throws Exception {
@@ -1284,6 +1283,89 @@
}
}
+ private void test_UnknownUnmappedKeyOID(CertificateFactory f) throws Exception {
+ byte[] certBytes = generateFakeOidCertificate();
+
+ {
+ X509Certificate cert = (X509Certificate) f
+ .generateCertificate(new ByteArrayInputStream(certBytes));
+ assertEquals(FakeOidProvider.SIGALG_OID, cert.getSigAlgOID());
+ assertEquals(FakeOidProvider.SIGALG_OID, cert.getSigAlgName());
+ }
+ }
+
+ private void test_UnknownMappedKeyOID(CertificateFactory f) throws Exception {
+ AlgNameMapper.addMapping(FakeOidProvider.SIGALG_OID, FakeOidProvider.SIGALG_OID_NAME);
+
+ Security.addProvider(new FakeOidProvider());
+ try {
+ byte[] certBytes = generateFakeOidCertificate();
+
+ // Make sure the certificate is outputting something.
+ X509Certificate cert = (X509Certificate) f
+ .generateCertificate(new ByteArrayInputStream(certBytes));
+ assertEquals(FakeOidProvider.SIGALG_OID, cert.getSigAlgOID());
+ if ("AndroidOpenSSL".equals(f.getProvider().getName())) {
+ // AndroidOpenSSL provider has a connection to AlgNameMapper, so
+ // we expect it to get our special name.
+ assertEquals(FakeOidProvider.SIGALG_OID_NAME, cert.getSigAlgName());
+ } else {
+ assertNotNull(cert.getSigAlgName());
+ }
+
+ cert.verify(cert.getPublicKey());
+ } finally {
+ AlgNameMapper
+ .removeMapping(FakeOidProvider.SIGALG_OID, FakeOidProvider.SIGALG_OID_NAME);
+ Security.removeProvider(FakeOidProvider.PROVIDER_NAME);
+ }
+ }
+
+ private byte[] generateFakeOidCertificate() throws IOException {
+ byte[] certBytes;
+
+ // Read in the original cert.
+ {
+ InputStream is = null;
+ try {
+ is = Support_Resources.getStream(CERT_RSA);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[2048];
+ int numRead;
+ while ((numRead = is.read(buffer, 0, buffer.length)) != -1) {
+ baos.write(buffer, 0, numRead);
+ }
+ certBytes = baos.toByteArray();
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ }
+
+ // Fix the OID for the certificate.
+ {
+ int numFixed = 0;
+ for (int i = 0; i < certBytes.length - 5; i++) {
+ if (certBytes[i] == (byte) 0x2A && certBytes[i + 1] == (byte) 0x86
+ && certBytes[i + 2] == (byte) 0x48 && certBytes[i + 3] == (byte) 0x86
+ && certBytes[i + 4] == (byte) 0xF7) {
+ certBytes[i + 1] = (byte) 0xFF;
+ certBytes[i + 2] = (byte) 0xFF;
+ certBytes[i + 3] = (byte) 0xFF;
+ i += 4;
+ numFixed++;
+ }
+ }
+ assertEquals(3, numFixed);
+ }
+ return certBytes;
+ }
+
@Override
protected void setUp() throws Exception {
super.setUp();
diff --git a/luni/src/test/java/libcore/java/text/OldBidiTest.java b/luni/src/test/java/libcore/java/text/OldBidiTest.java
index 45fe258..fbf68ea 100644
--- a/luni/src/test/java/libcore/java/text/OldBidiTest.java
+++ b/luni/src/test/java/libcore/java/text/OldBidiTest.java
@@ -70,4 +70,126 @@
assertEquals(1, bd.getRunStart(1));
assertEquals(2, bd.getRunStart(2));
}
+
+ public void testReorderVisuallyIllegalArguments() {
+ // Negative index.
+ try {
+ Bidi.reorderVisually(new byte[] {}, -1, new Object[] {}, 0, 0);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ try {
+ Bidi.reorderVisually(new byte[] {}, 0, new Object[] {}, -1, 0);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ try {
+ Bidi.reorderVisually(new byte[] {}, 0, new Object[] {}, 0, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ // Count > levels.length.
+ try {
+ Bidi.reorderVisually(new byte[] {}, 0, new Object[] {}, 0, 1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ // Count > levels.length - levelStart.
+ try {
+ Bidi.reorderVisually(new byte[] {1, 2, 3}, 2, new Object[] {}, 0, 2);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+ }
+
+ public void testRequiresBidiIllegalArguments() {
+ // Negative param.
+ try {
+ Bidi.requiresBidi(new char[] {}, 0, -1);
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ try {
+ Bidi.requiresBidi(new char[] {}, -1, 0);
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ // Limit > start.
+ try {
+ Bidi.requiresBidi(new char[] {}, 1, 0);
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ // Limit > text.length.
+ try {
+ Bidi.requiresBidi(new char[] {'a', 'b', 'c'}, 0, 4);
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+ }
+
+ public void testCreateLineBidiIllegalArguments() {
+ Bidi bidi = new Bidi("test", Bidi.DIRECTION_LEFT_TO_RIGHT);
+
+ try {
+ bidi.createLineBidi(-1, 0);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ try {
+ bidi.createLineBidi(0, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ // Linelimit > getLength().
+ try {
+ bidi.createLineBidi(0, 5);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ // lineStart > lineLimit.
+ try {
+ bidi.createLineBidi(2, 1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+ }
+
+ public void testConstructorIllegalArguments() {
+ try {
+ new Bidi(null, Bidi.DIRECTION_LEFT_TO_RIGHT);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+
+ // text.length - textStart < paragraphLength.
+ try {
+ new Bidi(new char[] {'a', 'b', 'c', 'd', 'e'}, 1, new byte[] {}, 0, 5,
+ Bidi.DIRECTION_LEFT_TO_RIGHT);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ // Expected.
+ }
+ }
+
}
diff --git a/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java b/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java
index 7a5fc4a..04396f4 100644
--- a/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java
@@ -17,7 +17,6 @@
package libcore.java.util;
-import dalvik.annotation.AndroidOnly;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
@@ -103,7 +102,6 @@
assertEquals("Pacific Standard Time", tz.getDisplayName(false, TimeZone.LONG));
}
- @AndroidOnly("fail on RI. See comment below")
public void test_getDisplayNameZILjava_util_Locale() {
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG, Locale.US));
diff --git a/luni/src/test/java/libcore/java/util/zip/DeflaterOutputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/DeflaterOutputStreamTest.java
index 2e32f7d..6b25f08 100644
--- a/luni/src/test/java/libcore/java/util/zip/DeflaterOutputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/DeflaterOutputStreamTest.java
@@ -101,6 +101,13 @@
}
}
+ static class FlushingDeflater extends Deflater {
+ @Override
+ public int deflate(byte[] buf, int offset, int byteCount) {
+ return super.deflate(buf, offset, byteCount, Deflater.SYNC_FLUSH);
+ }
+ }
+
/**
* Confirm that a DeflaterOutputStream constructed with Deflater
* with flushParm == SYNC_FLUSH does not need to to be flushed.
@@ -108,11 +115,7 @@
* http://b/4005091
*/
public void testSyncFlushDeflater() throws Exception {
- Deflater def = new Deflater();
- Field f = def.getClass().getDeclaredField("flushParm");
- f.setAccessible(true);
- f.setInt(def, Deflater.SYNC_FLUSH);
-
+ Deflater def = new FlushingDeflater();
final int deflaterBufferSize = 512;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(baos, def, deflaterBufferSize);
diff --git a/luni/src/test/java/libcore/java/util/zip/Zip64Test.java b/luni/src/test/java/libcore/java/util/zip/Zip64Test.java
new file mode 100644
index 0000000..e4b5baf
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/zip/Zip64Test.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015 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 libcore.java.util.zip;
+
+import junit.framework.TestCase;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.zip.Zip64;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+
+public class Zip64Test extends TestCase {
+
+ // We shouldn't attempt to look inside the extended info if we have valid fields
+ // in the regular file header / central directory entry.
+ public void testParseZip64ExtendedInfo_noFieldsPresent() throws Exception {
+ ZipEntry ze = createZipEntry(null, 100, 200, ZipEntry.STORED, 300);
+ Zip64.parseZip64ExtendedInfo(ze, false /* fromCentralDirectory */);
+ Zip64.parseZip64ExtendedInfo(ze, true /* fromCentralDirectory */);
+ }
+
+ // We *should* attempt to look in the extended info if the local file header / central
+ // directory entry don't have the correct values.
+ public void testParseZip64ExtendedInfo_missingExtendedInfo() throws Exception {
+ ZipEntry ze = createZipEntry(null, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE,
+ Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE, ZipEntry.STORED, 300);
+ try {
+ Zip64.parseZip64ExtendedInfo(ze, false /* fromCentralDirectory */);
+ fail();
+ } catch (ZipException expected) {
+ }
+
+ try {
+ Zip64.parseZip64ExtendedInfo(ze, true /* fromCentralDirectory */);
+ fail();
+ } catch (ZipException expected) {
+ }
+ }
+
+ // Test the case where the compressed / uncompressed sizes are in the extended info
+ // but the header offset isn't.
+ public void testParseZip64ExtendedInfo_partialInfo() throws Exception {
+ byte[] extras = new byte[20];
+ ByteBuffer buf = ByteBuffer.wrap(extras);
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ buf.putShort((short) 0x0001);
+ buf.putShort((short) 16);
+ buf.putLong(50);
+ buf.putLong(100);
+
+ ZipEntry ze = createZipEntry(extras, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE,
+ Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE, ZipEntry.STORED, 300);
+
+ Zip64.parseZip64ExtendedInfo(ze, false /*fromCentralDirectory */);
+ assertEquals(50, ze.getSize());
+ assertEquals(100, ze.getCompressedSize());
+
+ ze = createZipEntry(extras, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE,
+ Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE, ZipEntry.STORED, 300);
+ Zip64.parseZip64ExtendedInfo(ze, true /*fromCentralDirectory */);
+ assertEquals(50, ze.getSize());
+ assertEquals(100, ze.getCompressedSize());
+ }
+
+ public void testInsertZip64ExtendedInfo() throws Exception {
+ ZipEntry ze = createZipEntry(null, Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE + 300,
+ Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE + 500, ZipEntry.STORED, 300);
+ Zip64.insertZip64ExtendedInfoToExtras(ze);
+
+ assertNotNull(ze.getExtra());
+ ByteBuffer buf = ByteBuffer.wrap(ze.getExtra());
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ assertEquals(0x0001, buf.getShort());
+ assertEquals(24, buf.getShort());
+ assertEquals(Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE + 300, buf.getLong());
+ assertEquals(Zip64.MAX_ZIP_ENTRY_AND_ARCHIVE_SIZE + 500, buf.getLong());
+ }
+
+ private static ZipEntry createZipEntry(byte[] extras, long size, long compressedSize,
+ int compressionMethod, long headerOffset) {
+ return new ZipEntry("name", "comment", 42 /* crc */, compressedSize, size,
+ compressionMethod, 42 /* time */, 42 /* modDate */, extras, headerOffset,
+ 42 /* data offset */);
+ }
+}
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java
index 49990a3..1dc22ca 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java
@@ -18,6 +18,9 @@
import java.io.ByteArrayInputStream;
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.nio.charset.Charset;
@@ -29,6 +32,7 @@
import java.util.Random;
import java.util.Set;
import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
@@ -82,4 +86,33 @@
in.close();
}
}
+
+ // NOTE: Using octal because it's easiest to use "hexdump -b" to dump file contents.
+ private static final byte[] INCOMPLETE_ZIP = new byte[] {
+ 0120, 0113, 0003, 0004, 0024, 0000, 0010, 0010, 0010, 0000, 0002, 0035, (byte) 0330,
+ 0106, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0013,
+ 0000, 0000, 0000, 0146, 0157, 0157, 0057, 0142, 0141, 0162, 0056, 0160, 0156, 0147 };
+
+ // http://b//21846904
+ public void testReadOnIncompleteStream() throws Exception {
+ ZipInputStream zi = new ZipInputStream(new ByteArrayInputStream(INCOMPLETE_ZIP));
+ ZipEntry ze = zi.getNextEntry();
+
+ // read() and closeEntry() must throw IOExceptions to indicate that
+ // the stream is corrupt. The bug above reported that they would loop
+ // forever.
+ try {
+ zi.read(new byte[1024], 0, 1024);
+ fail();
+ } catch (IOException expected) {
+ }
+
+ try {
+ zi.closeEntry();
+ fail();
+ } catch (IOException expected) {
+ }
+
+ zi.close();
+ }
}
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
index afd2e59..13d54b4 100644
--- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
@@ -27,6 +27,7 @@
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
@@ -988,24 +989,129 @@
Security.addProvider(mockProviderInvalid);
try {
Cipher c = Cipher.getInstance("FOO");
- if (StandardNames.IS_RI) {
- c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[16], "FOO"));
- } else {
- fail("Should not find any matching providers; found: " + c);
- }
- } catch (NoSuchAlgorithmException maybe) {
- if (StandardNames.IS_RI) {
- throw maybe;
- }
- } catch (ClassCastException maybe) {
- if (!StandardNames.IS_RI) {
- throw maybe;
- }
+ c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[16], "FOO"));
+ fail("Should not find any matching providers; found: " + c);
+ } catch (ClassCastException expected) {
} finally {
Security.removeProvider(mockProviderInvalid.getName());
}
}
+ public void testCipher_init_CallsInitWithParams_AlgorithmParameterSpec() throws Exception {
+ Provider mockProviderRejects = new MockProvider("MockProviderRejects") {
+ public void setup() {
+ put("Cipher.FOO",
+ MockCipherSpi.MustInitWithAlgorithmParameterSpec_RejectsAll.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+ Provider mockProviderAccepts = new MockProvider("MockProviderAccepts") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderRejects);
+ Security.addProvider(mockProviderAccepts);
+ try {
+ Cipher c = Cipher.getInstance("FOO");
+ c.init(Cipher.ENCRYPT_MODE, new MockKey(), new IvParameterSpec(new byte[12]));
+ assertEquals(mockProviderAccepts, c.getProvider());
+ } finally {
+ Security.removeProvider(mockProviderRejects.getName());
+ Security.removeProvider(mockProviderAccepts.getName());
+ }
+ }
+
+ public void testCipher_init_CallsInitWithParams_AlgorithmParameters() throws Exception {
+ Provider mockProviderRejects = new MockProvider("MockProviderRejects") {
+ public void setup() {
+ put("Cipher.FOO",
+ MockCipherSpi.MustInitWithAlgorithmParameters_RejectsAll.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+ Provider mockProviderAccepts = new MockProvider("MockProviderAccepts") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderRejects);
+ Security.addProvider(mockProviderAccepts);
+ try {
+ Cipher c = Cipher.getInstance("FOO");
+ c.init(Cipher.ENCRYPT_MODE, new MockKey(), AlgorithmParameters.getInstance("AES"));
+ assertEquals(mockProviderAccepts, c.getProvider());
+ } finally {
+ Security.removeProvider(mockProviderRejects.getName());
+ Security.removeProvider(mockProviderAccepts.getName());
+ }
+ }
+
+ public void testCipher_init_CallsInitIgnoresRuntimeException() throws Exception {
+ Provider mockProviderRejects = new MockProvider("MockProviderRejects") {
+ public void setup() {
+ put("Cipher.FOO",
+ MockCipherSpi.MustInitWithAlgorithmParameters_ThrowsNull.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+ Provider mockProviderAccepts = new MockProvider("MockProviderAccepts") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderRejects);
+ Security.addProvider(mockProviderAccepts);
+ try {
+ Cipher c = Cipher.getInstance("FOO");
+ c.init(Cipher.ENCRYPT_MODE, new MockKey(), AlgorithmParameters.getInstance("AES"));
+ assertEquals(mockProviderAccepts, c.getProvider());
+ } finally {
+ Security.removeProvider(mockProviderRejects.getName());
+ Security.removeProvider(mockProviderAccepts.getName());
+ }
+ }
+
+ public void testCipher_init_CallsInitWithMode() throws Exception {
+ Provider mockProviderOnlyEncrypt = new MockProvider("MockProviderOnlyEncrypt") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.MustInitForEncryptModeOrRejects.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+ Provider mockProviderAcceptsAll = new MockProvider("MockProviderAcceptsAll") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ put("Cipher.FOO SupportedKeyClasses", MockKey.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProviderOnlyEncrypt);
+ Security.addProvider(mockProviderAcceptsAll);
+ try {
+ {
+ Cipher c = Cipher.getInstance("FOO");
+ c.init(Cipher.DECRYPT_MODE, new MockKey(), AlgorithmParameters.getInstance("AES"));
+ assertEquals(mockProviderAcceptsAll, c.getProvider());
+ }
+
+ {
+ Cipher c = Cipher.getInstance("FOO");
+ c.init(Cipher.ENCRYPT_MODE, new MockKey(), AlgorithmParameters.getInstance("AES"));
+ assertEquals(mockProviderOnlyEncrypt, c.getProvider());
+ }
+ } finally {
+ Security.removeProvider(mockProviderOnlyEncrypt.getName());
+ Security.removeProvider(mockProviderAcceptsAll.getName());
+ }
+ }
+
public void test_getInstance() throws Exception {
final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
PrintStream out = new PrintStream(errBuffer);
@@ -1162,6 +1268,57 @@
c.doFinal(new byte[1]).length);
}
+ if (isPBE(algorithm)) {
+ if (algorithm.endsWith("RC4")) {
+ assertNull(cipherID + " getIV()", c.getIV());
+ } else {
+ assertNotNull(cipherID + " getIV()", c.getIV());
+ }
+ } else if (encryptSpec instanceof IvParameterSpec) {
+ assertEquals(cipherID + " getIV()",
+ Arrays.toString(((IvParameterSpec) encryptSpec).getIV()),
+ Arrays.toString(c.getIV()));
+ } else if (encryptSpec instanceof GCMParameterSpec) {
+ assertNotNull(c.getIV());
+ assertEquals(cipherID + " getIV()",
+ Arrays.toString(((GCMParameterSpec) encryptSpec).getIV()),
+ Arrays.toString(c.getIV()));
+ } else {
+ try {
+ assertNull(cipherID + " getIV()", c.getIV());
+ } catch (NullPointerException e) {
+ // Bouncycastle apparently has a bug here with AESWRAP, et al.
+ if (!("BC".equals(providerName) && isOnlyWrappingAlgorithm(algorithm))) {
+ throw e;
+ }
+ }
+ }
+
+ AlgorithmParameters encParams = c.getParameters();
+ if (encryptSpec == null) {
+ assertNull(cipherID + " getParameters()", encParams);
+ } else if (encryptSpec instanceof GCMParameterSpec) {
+ GCMParameterSpec gcmDecryptSpec = (GCMParameterSpec) encParams
+ .getParameterSpec(GCMParameterSpec.class);
+ assertEquals(cipherID + " getIV()",
+ Arrays.toString(((GCMParameterSpec) encryptSpec).getIV()),
+ Arrays.toString(gcmDecryptSpec.getIV()));
+ assertEquals(cipherID + " getTLen()", ((GCMParameterSpec) encryptSpec).getTLen(),
+ gcmDecryptSpec.getTLen());
+ } else if (encryptSpec instanceof IvParameterSpec) {
+ IvParameterSpec ivDecryptSpec = (IvParameterSpec) encParams
+ .getParameterSpec(IvParameterSpec.class);
+ assertEquals(cipherID + " getIV()",
+ Arrays.toString(((IvParameterSpec) encryptSpec).getIV()),
+ Arrays.toString(ivDecryptSpec.getIV()));
+ } else if (encryptSpec instanceof PBEParameterSpec) {
+ // Bouncycastle seems to be undecided about whether it returns this
+ // or not
+ if (!"BC".equals(providerName)) {
+ assertNotNull(cipherID + " getParameters()", encParams);
+ }
+ }
+
final AlgorithmParameterSpec decryptSpec = getDecryptAlgorithmParameterSpec(encryptSpec, c);
int decryptMode = getDecryptMode(algorithm);
@@ -1199,18 +1356,27 @@
}
}
- AlgorithmParameters params = c.getParameters();
+ AlgorithmParameters decParams = c.getParameters();
if (decryptSpec == null) {
- assertNull(cipherID + " getParameters()", params);
+ assertNull(cipherID + " getParameters()", decParams);
+ } else if (decryptSpec instanceof GCMParameterSpec) {
+ GCMParameterSpec gcmDecryptSpec = (GCMParameterSpec) decParams
+ .getParameterSpec(GCMParameterSpec.class);
+ assertEquals(cipherID + " getIV()",
+ Arrays.toString(((GCMParameterSpec) decryptSpec).getIV()),
+ Arrays.toString(gcmDecryptSpec.getIV()));
+ assertEquals(cipherID + " getTLen()", ((GCMParameterSpec) decryptSpec).getTLen(),
+ gcmDecryptSpec.getTLen());
} else if (decryptSpec instanceof IvParameterSpec) {
- IvParameterSpec ivDecryptSpec = (IvParameterSpec) params.getParameterSpec(IvParameterSpec.class);
+ IvParameterSpec ivDecryptSpec = (IvParameterSpec) decParams
+ .getParameterSpec(IvParameterSpec.class);
assertEquals(cipherID + " getIV()",
Arrays.toString(((IvParameterSpec) decryptSpec).getIV()),
Arrays.toString(ivDecryptSpec.getIV()));
} else if (decryptSpec instanceof PBEParameterSpec) {
- // Bouncycastle seems to be schizophrenic about whther it returns this or not
+ // Bouncycastle seems to be undecided about whether it returns this or not
if (!"BC".equals(providerName)) {
- assertNotNull(cipherID + " getParameters()", params);
+ assertNotNull(cipherID + " getParameters()", decParams);
}
}
@@ -3388,4 +3554,63 @@
assertEquals("", new String(buffer, 0, bytesProduced, StandardCharsets.US_ASCII));
}
}
+
+ /**
+ * If a provider rejects a key for "Cipher/Mode/Padding"", there might be another that
+ * accepts the key for "Cipher". Don't throw InvalidKeyException when trying the first one.
+ * http://b/22208820
+ */
+ public void testCipher_init_tryAllCombinationsBeforeThrowingInvalidKey()
+ throws Exception {
+ Provider mockProvider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Cipher.FOO/FOO/FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ put("Cipher.FOO/FOO/FOO SupportedKeyClasses", "none");
+ }
+ };
+
+ Provider mockProvider2 = new MockProvider("MockProvider2") {
+ public void setup() {
+ put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+ }
+ };
+
+ Security.addProvider(mockProvider);
+
+ try {
+ try {
+ // The provider installed doesn't accept the key.
+ Cipher c = Cipher.getInstance("FOO/FOO/FOO");
+ c.init(Cipher.DECRYPT_MODE, new MockKey());
+ fail("Expected InvalidKeyException");
+ } catch (InvalidKeyException expected) {
+ }
+
+ Security.addProvider(mockProvider2);
+
+ try {
+ // The new provider accepts "FOO" with this key. Use it despite the other provider
+ // accepts "FOO/FOO/FOO" but doesn't accept the key.
+ Cipher c = Cipher.getInstance("FOO/FOO/FOO");
+ c.init(Cipher.DECRYPT_MODE, new MockKey());
+ assertEquals("MockProvider2", c.getProvider().getName());
+ } finally {
+ Security.removeProvider(mockProvider2.getName());
+ }
+ } finally {
+ Security.removeProvider(mockProvider.getName());
+ }
+ }
+
+ /**
+ * Check that RSA with OAEPPadding is supported.
+ * http://b/22208820
+ */
+ public void test_RSA_OAEPPadding() throws Exception {
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+ keyGen.initialize(1024, SecureRandom.getInstance("SHA1PRNG"));
+ Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPPadding");
+ cipher.init(Cipher.ENCRYPT_MODE, keyGen.generateKeyPair().getPublic());
+ cipher.doFinal(new byte[] {1,2,3,4});
+ }
}
diff --git a/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java b/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java
index 6742cf3..c1b1bd2 100644
--- a/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java
+++ b/luni/src/test/java/libcore/javax/crypto/MockCipherSpi.java
@@ -25,6 +25,7 @@
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
import javax.crypto.CipherSpi;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
@@ -56,6 +57,92 @@
public static class AllKeyTypes extends MockCipherSpi {
}
+ public static class MustInitWithAlgorithmParameterSpec_RejectsAll extends MockCipherSpi {
+ @Override
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ throw new AssertionError("Must have AlgorithmParameterSpec");
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ throw new InvalidAlgorithmParameterException("expected rejection");
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ throw new AssertionError("Must have AlgorithmParameterSpec");
+ }
+ }
+
+ public static class MustInitWithAlgorithmParameters_RejectsAll extends MockCipherSpi {
+ @Override
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ throw new AssertionError("Must have AlgorithmParameterSpec");
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ throw new AssertionError("Must have AlgorithmParameterSpec");
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ throw new InvalidAlgorithmParameterException("expected rejection");
+ }
+ }
+
+ public static class MustInitWithAlgorithmParameters_ThrowsNull extends MockCipherSpi {
+ @Override
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ throw new NullPointerException("expected rejection");
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ throw new NullPointerException("expected rejection");
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ throw new NullPointerException("expected rejection");
+ }
+ }
+
+ public static class MustInitForEncryptModeOrRejects extends MockCipherSpi {
+ @Override
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ if (opmode != Cipher.ENCRYPT_MODE) {
+ throw new InvalidKeyException("expected rejection");
+ }
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (opmode != Cipher.ENCRYPT_MODE) {
+ throw new InvalidKeyException("expected rejection");
+ }
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (opmode != Cipher.ENCRYPT_MODE) {
+ throw new InvalidKeyException("expected rejection");
+ }
+ }
+ }
+
public void checkKeyType(Key key) throws InvalidKeyException {
}
diff --git a/luni/src/test/java/libcore/javax/crypto/MockKey.java b/luni/src/test/java/libcore/javax/crypto/MockKey.java
index 248e2de..1c758f3 100644
--- a/luni/src/test/java/libcore/javax/crypto/MockKey.java
+++ b/luni/src/test/java/libcore/javax/crypto/MockKey.java
@@ -25,7 +25,7 @@
public class MockKey implements Key {
@Override
public String getAlgorithm() {
- throw new UnsupportedOperationException("not implemented");
+ return "MOCK";
}
@Override
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
index e64fb9e..b3ff4ad7 100644
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
+++ b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
@@ -15,7 +15,6 @@
*/
package libcore.javax.crypto.spec;
-import dalvik.annotation.BrokenTest;
import tests.security.AlgorithmParameterGeneratorTest;
import tests.security.AlgorithmParameterKeyAgreementHelper;
@@ -26,9 +25,7 @@
super("DH", new AlgorithmParameterKeyAgreementHelper("DH"));
}
- // Broken Test: Suffers from DH slowness, disabling for now
public void testAlgorithmParameterGenerator() {
super.testAlgorithmParameterGenerator();
}
-
}
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java
index f21374f..da070b6 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java
@@ -15,8 +15,6 @@
*/
package org.apache.harmony.crypto.tests.javax.crypto.func;
-import dalvik.annotation.AndroidOnly;
-
import junit.framework.TestCase;
public class CipherPBETest extends TestCase {
@@ -32,7 +30,6 @@
.getTotalFailuresNumber());
}
- @AndroidOnly("Not supported by RI (maybe with a different name)")
public void test_PBEWithSHAand3KeyTripleDES() throws Exception {
CipherPBEThread PBEWITHSHAAND3KEYTRIPLEDESCBC = new CipherPBEThread(
"PBEWITHSHAAND3-KEYTRIPLEDES-CBC", new int[] {112, 168},
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java
index acb06ae..95f4191 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java
@@ -15,12 +15,9 @@
*/
package org.apache.harmony.crypto.tests.javax.crypto.func;
-import dalvik.annotation.BrokenTest;
-
import junit.framework.TestCase;
public class KeyAgreementFunctionalTest extends TestCase {
- @BrokenTest("Too slow - disabling for now")
public void test_KeyAgreement() throws Exception {
String[] algArray = {"DES", "DESede"};
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
index 471d670..bc7b338 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
@@ -22,8 +22,6 @@
package org.apache.harmony.crypto.tests.javax.crypto.interfaces;
-import dalvik.annotation.BrokenTest;
-
import junit.framework.TestCase;
import java.math.BigInteger;
@@ -51,7 +49,6 @@
-6628103563352519193L);
}
- @BrokenTest("Too slow - disabling for now")
public void test_getParams() throws Exception {
KeyPairGenerator kg = KeyPairGenerator.getInstance("DH");
kg.initialize(1024);
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
index 3625dee..1362fc6 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
@@ -17,7 +17,6 @@
package org.apache.harmony.security.tests.java.security;
-import dalvik.annotation.AndroidOnly;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
@@ -259,8 +258,8 @@
/**
* java.security.Identity#removeCertificate(java.security.Certificate)
*/
- @AndroidOnly("Spec says: Removing unknown certificates throw an exception. "
- + "The RI ignores unknown certificates.")
+ // AndroidOnly("Spec says: Removing unknown certificates throw an exception. "
+ // + "The RI ignores unknown certificates.")
public void test_removeCertificateLjava_security_Certificate() throws Exception {
IdentitySubclass sub = new IdentitySubclass("test",
new IdentityScopeSubclass());
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/SecureRandom2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/SecureRandom2Test.java
index aa0ec67..77588f6 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/SecureRandom2Test.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/SecureRandom2Test.java
@@ -293,53 +293,8 @@
}
/**
- * Two {@link SecureRandom} objects, created with
- * {@link SecureRandom#getInstance(String)} and initialized before use
- * with the same seed, should return the same results.<p>
- *
- * In the future, it may sense to disallow seeding {@code SecureRandom},
- * as it tends to be error prone and open up security holes.
- * See {@link SecureRandom} for more details about insecure seeding.
- *
- * Note that this only works with the Harmony "Crypto" provider.
- */
- public void testSameSeedGeneratesSameResults() throws Exception {
- byte[] seed1 = { 'a', 'b', 'c' };
- SecureRandom sr1 = SecureRandom.getInstance("SHA1PRNG", "Crypto");
- sr1.setSeed(seed1);
-
- byte[] seed2 = { 'a', 'b', 'c' };
- SecureRandom sr2 = SecureRandom.getInstance("SHA1PRNG", "Crypto");
- sr2.setSeed(seed2);
-
- assertTrue(sr1.nextLong() == sr2.nextLong());
- }
-
- /**
- * Assert that a {@link SecureRandom} object seeded from a constant
- * seed always returns the same value, even across VM restarts.
- *
- * Future versions of Android may change the implementation of
- * SHA1PRNG, so users of {@code SecureRandom} should not assume
- * the same seed will always produce the same value. This test
- * is not a guarantee of future compatibility.
- *
- * In fact, this test only works with the Harmony "Crypto" provider.
- */
- public void testAlwaysSameValueWithSameSeed() throws Exception {
- byte[] seed1 = { 'a', 'b', 'c' };
- SecureRandom sr1 = SecureRandom.getInstance("SHA1PRNG", "Crypto");
- sr1.setSeed(seed1);
-
- // This long value has no special meaning and may change in the future.
- assertEquals(6180693691264871500l, sr1.nextLong());
- }
-
- /**
* Validate that calling {@link SecureRandom#setSeed} <b>after</b> generating
* a random number compliments, but doesn't replace, the existing seed.
- *
- * Compare this test to {@link #testAlwaysSameValueWithSameSeed()}.
*/
public void testSetSeedComplimentsAfterFirstRandomNumber() throws Exception {
byte[] seed1 = { 'a', 'b', 'c' };
diff --git a/luni/src/test/java/tests/security/cert/X509CRLSelector2Test.java b/luni/src/test/java/tests/security/cert/X509CRLSelector2Test.java
index f2e814d..1e4dce9 100644
--- a/luni/src/test/java/tests/security/cert/X509CRLSelector2Test.java
+++ b/luni/src/test/java/tests/security/cert/X509CRLSelector2Test.java
@@ -1,7 +1,5 @@
package tests.security.cert;
-import dalvik.annotation.AndroidOnly;
-
import junit.framework.TestCase;
import org.apache.harmony.security.asn1.ASN1Integer;
@@ -237,8 +235,6 @@
* criteria, if specified minCRL value matches the selector, and if CRL with
* inappropriate crlNumber value does not match the selector.
*/
- @AndroidOnly("Uses specific class: " +
- "org.apache.harmony.security.asn1.ASN1OctetString.")
public void testSetMinCRLNumberLjava_math_BigInteger() {
X509CRLSelector selector = new X509CRLSelector();
BigInteger minCRL = new BigInteger("10000");
@@ -261,8 +257,6 @@
* criteria, if specified maxCRL value matches the selector, and if CRL with
* inappropriate crlNumber value does not match the selector.
*/
- @AndroidOnly("Uses specific class: " +
- "org.apache.harmony.security.asn1.ASN1OctetString.")
public void testSetMaxCRLNumberLjava_math_BigInteger() {
X509CRLSelector selector = new X509CRLSelector();
BigInteger maxCRL = new BigInteger("10000");
@@ -459,9 +453,6 @@
* crl which matche to the initial selector should match to the clone and
* the change of clone should not cause the change of initial selector.
*/
- @AndroidOnly("Uses specific classes: " +
- "org.apache.harmony.security.asn1.ASN1OctetString, " +
- "org.apache.harmony.security.asn1.ASN1Integer.")
public void testClone() {
X509CRLSelector selector = new X509CRLSelector();
X500Principal iss1 = new X500Principal("O=First Org.");
diff --git a/luni/src/test/java/tests/security/cert/X509CRLTest.java b/luni/src/test/java/tests/security/cert/X509CRLTest.java
index c0163f3..746da9a 100644
--- a/luni/src/test/java/tests/security/cert/X509CRLTest.java
+++ b/luni/src/test/java/tests/security/cert/X509CRLTest.java
@@ -22,8 +22,6 @@
package tests.security.cert;
-import dalvik.annotation.AndroidOnly;
-
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@@ -270,8 +268,8 @@
* Check if the default implementation throws NullPointerException
* on null input data.
*/
- @AndroidOnly("Test filed on RI: getRevokedCertificate throws " +
- "RuntimeException.")
+ // AndroidOnly("Test filed on RI: getRevokedCertificate throws " +
+ // "RuntimeException.")
public void testGetRevokedCertificate() {
try {
tbt_crl.getRevokedCertificate((X509Certificate) null);
diff --git a/luni/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java b/luni/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java
index 6cebda5..5f4abdd 100644
--- a/luni/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java
+++ b/luni/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java
@@ -32,9 +32,7 @@
*/
public void test_getX() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
- keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G),
- new SecureRandom(new MySecureRandomSpi(), null) {
- });
+ keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G), new SecureRandom());
KeyPair keyPair = keyGen.generateKeyPair();
DSAPrivateKey key = (DSAPrivateKey) keyPair.getPrivate();
assertNotNull("Invalid X value", key.getX());
diff --git a/luni/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java b/luni/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java
index 9fe4910..09e936d 100644
--- a/luni/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java
+++ b/luni/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java
@@ -42,9 +42,7 @@
// Case 1: check with predefined p, q, g, x
keyGen = KeyPairGenerator.getInstance("DSA");
- keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G),
- new SecureRandom(new MySecureRandomSpi(), null) {
- });
+ keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G), new SecureRandom());
keys = keyGen.generateKeyPair();
priv = (DSAPrivateKey) keys.getPrivate();
publ = (DSAPublicKey) keys.getPublic();
diff --git a/luni/src/test/java/tests/targets/security/MessageDigestTestMD2.java b/luni/src/test/java/tests/targets/security/MessageDigestTestMD2.java
index 6811bc0..4483da4 100644
--- a/luni/src/test/java/tests/targets/security/MessageDigestTestMD2.java
+++ b/luni/src/test/java/tests/targets/security/MessageDigestTestMD2.java
@@ -15,7 +15,6 @@
*/
package tests.targets.security;
-import dalvik.annotation.AndroidOnly;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
@@ -24,7 +23,6 @@
public class MessageDigestTestMD2 extends TestCase {
- @AndroidOnly("Android doesn't include MD2 message digest algorithm")
public void testMessageDigest1() throws Exception{
try {
MessageDigest digest = MessageDigest.getInstance("MD2");
@@ -42,7 +40,6 @@
}
}
- @AndroidOnly("Android allows usage of MD2 in third party providers")
public void testMessageDigest2() throws Exception{
Provider provider = new MyProvider();
diff --git a/luni/src/test/java/tests/targets/security/SignatureTestMD2withRSA.java b/luni/src/test/java/tests/targets/security/SignatureTestMD2withRSA.java
index c9126ef..90ac2fa 100644
--- a/luni/src/test/java/tests/targets/security/SignatureTestMD2withRSA.java
+++ b/luni/src/test/java/tests/targets/security/SignatureTestMD2withRSA.java
@@ -15,7 +15,6 @@
*/
package tests.targets.security;
-import dalvik.annotation.AndroidOnly;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.NoSuchAlgorithmException;
@@ -29,7 +28,6 @@
public class SignatureTestMD2withRSA extends TestCase {
- @AndroidOnly("Android doesn't include MD2withRSA signature algorithm")
public void testSignature() {
// MD2 must not be part of android.
@@ -91,7 +89,6 @@
}
}
- @AndroidOnly("Android allows usage of MD2withRSA in third party providers")
public void testSignature2() throws Exception{
Provider provider = new MyProvider();
diff --git a/luni/src/test/java/tests/targets/security/cert/CertificateTest.java b/luni/src/test/java/tests/targets/security/cert/CertificateTest.java
index dd06249..8044f4f 100644
--- a/luni/src/test/java/tests/targets/security/cert/CertificateTest.java
+++ b/luni/src/test/java/tests/targets/security/cert/CertificateTest.java
@@ -15,7 +15,6 @@
*/
package tests.targets.security.cert;
-import dalvik.annotation.AndroidOnly;
import java.io.ByteArrayInputStream;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
@@ -602,7 +601,6 @@
}
}
- @AndroidOnly("MD2 is not supported by Android")
public void testVerifyMD2() throws Exception {
Provider[] providers = Security.getProviders("CertificateFactory.X509");
for (Provider provider : providers) {
diff --git a/tzdata/update/src/main/libcore/tzdata/update/ConfigBundle.java b/tzdata/update/src/main/libcore/tzdata/update/ConfigBundle.java
index 6e2ff9d..b497c85 100644
--- a/tzdata/update/src/main/libcore/tzdata/update/ConfigBundle.java
+++ b/tzdata/update/src/main/libcore/tzdata/update/ConfigBundle.java
@@ -72,6 +72,8 @@
// Validate the entry name: make sure the unpacked file will exist beneath the
// targetDir.
String name = entry.getName();
+ // Note, we assume that nothing will quickly insert a symlink after createSubFile()
+ // that might invalidate the guarantees about name existing beneath targetDir.
File entryFile = FileUtils.createSubFile(targetDir, name);
if (entry.isDirectory()) {
diff --git a/tzdata/update/src/main/libcore/tzdata/update/FileUtils.java b/tzdata/update/src/main/libcore/tzdata/update/FileUtils.java
index 8b7da78..652b786 100644
--- a/tzdata/update/src/main/libcore/tzdata/update/FileUtils.java
+++ b/tzdata/update/src/main/libcore/tzdata/update/FileUtils.java
@@ -37,19 +37,18 @@
/**
* Creates a new {@link java.io.File} from the {@code parentDir} and {@code name}, but only if
- * the
- * resulting file would exist beneath {@code parentDir}. Useful if {@code name} could contain
- * "/../" or symlinks. The returned object has an absolute path.
+ * the resulting file would exist beneath {@code parentDir}. Useful if {@code name} could
+ * contain "/../" or symlinks. The returned object has a canonicalized path.
*
- * @throws java.io.IOException
- * if the file would not exist beneath {@code parentDir}
+ * @throws java.io.IOException if the file would not exist beneath {@code parentDir}
*/
public static File createSubFile(File parentDir, String name) throws IOException {
// The subFile must exist beneath parentDir. If name contains "/../" this may not be the
// case so we check.
- File subFile = canonicalizeDirPath(new File(parentDir, name));
+ File subFile = new File(parentDir, name).getCanonicalFile();
if (!subFile.getPath().startsWith(parentDir.getCanonicalPath())) {
- throw new IOException(name + " must exist beneath " + parentDir);
+ throw new IOException(name + " must exist beneath " + parentDir +
+ ". Canonicalized subpath: " + subFile);
}
return subFile;
}
@@ -61,8 +60,8 @@
* directories explicitly created will have their permissions set; existing directories are
* untouched.
*
- * @throws IOException
- * if the directory or one of its parents did not already exist and could not be created
+ * @throws IOException if the directory or one of its parents did not already exist and could
+ * not be created
*/
public static void ensureDirectoriesExist(File dir, boolean makeWorldReadable)
throws IOException {
@@ -87,14 +86,6 @@
}
}
- /**
- * Returns a file with all symlinks and relative paths such as "/../" resolved <em>except</em>
- * for the base name (the last element of the path). Useful for detecting symlinks.
- */
- public static File canonicalizeDirPath(File file) throws IOException {
- return new File(file.getParentFile().getCanonicalFile(), file.getName());
- }
-
public static void makeDirectoryWorldAccessible(File directory) throws IOException {
if (!directory.isDirectory()) {
throw new IOException(directory + " must be a directory");
@@ -150,7 +141,10 @@
}
public static boolean isSymlink(File file) throws IOException {
- return !file.getCanonicalPath().equals(canonicalizeDirPath(file).getPath());
+ String baseName = file.getName();
+ String canonicalPathExceptBaseName =
+ new File(file.getParentFile().getCanonicalFile(), baseName).getPath();
+ return !file.getCanonicalPath().equals(canonicalPathExceptBaseName);
}
public static void deleteRecursive(File toDelete) throws IOException {
diff --git a/tzdata/update/src/test/libcore/tzdata/update/FileUtilsTest.java b/tzdata/update/src/test/libcore/tzdata/update/FileUtilsTest.java
index ce02bfe..d002820 100644
--- a/tzdata/update/src/test/libcore/tzdata/update/FileUtilsTest.java
+++ b/tzdata/update/src/test/libcore/tzdata/update/FileUtilsTest.java
@@ -113,21 +113,30 @@
}
public void testCreateSubFile() throws Exception {
- File dir1 = createTempDir();
- File subFile = FileUtils.createSubFile(dir1, "file");
- assertFileCanonicalEquals(new File(dir1, "file"), subFile);
+ File dir1 = createTempDir().getCanonicalFile();
+
+ File actualSubFile = FileUtils.createSubFile(dir1, "file");
+ assertEquals(new File(dir1, "file"), actualSubFile);
+
+ File existingSubFile = createRegularFile(dir1, "file");
+ actualSubFile = FileUtils.createSubFile(dir1, "file");
+ assertEquals(existingSubFile, actualSubFile);
+
+ File existingSubDir = createDir(dir1, "subdir");
+ actualSubFile = FileUtils.createSubFile(dir1, "subdir");
+ assertEquals(existingSubDir, actualSubFile);
assertCreateSubFileThrows(dir1, "../file");
assertCreateSubFileThrows(dir1, "../../file");
assertCreateSubFileThrows(dir1, "../otherdir/file");
- File dir2 = createTempDir();
- File dir2Subdir = createDir(dir2, "dir2Subdir");
- File expectedSymlinkToDir2 = createSymlink(dir2Subdir, dir1, "symlinkToDir2");
+ File dir2 = createTempDir().getCanonicalFile();
+ createSymlink(dir2, dir1, "symlinkToDir2");
+ assertCreateSubFileThrows(dir1, "symlinkToDir2");
- File actualSymlinkToDir2 = FileUtils.createSubFile(dir1, "symlinkToDir2");
- assertEquals(expectedSymlinkToDir2, actualSymlinkToDir2);
+ assertCreateSubFileThrows(dir1, "symlinkToDir2/fileInSymlinkedDir");
+ createRegularFile(dir1, "symlinkToDir2/fileInSymlinkedDir");
assertCreateSubFileThrows(dir1, "symlinkToDir2/fileInSymlinkedDir");
}
@@ -295,10 +304,6 @@
(sb.st_mode & mask) == mask);
}
- private static void assertFileCanonicalEquals(File expected, File actual) throws IOException {
- assertEquals(expected.getCanonicalFile(), actual.getCanonicalFile());
- }
-
private File createTempDir() {
final String tempPrefix = getClass().getSimpleName();
File tempDir = IoUtils.createTemporaryDirectory(tempPrefix);
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
index 0958bbf..bb3d130 100644
--- a/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParser.java
@@ -916,7 +916,7 @@
* Get next parsing event - element content will be coalesced and only one
* TEXT event must be returned for whole element content
* (comments and processing instructions will be ignored and entity references
- * must be expanded or exception mus be thrown if entity reference can not be expanded).
+ * must be expanded or exception must be thrown if entity reference can not be expanded).
* If element content is empty (content is "") then no TEXT event will be reported.
*
* <p><b>NOTE:</b> empty element (such as <tag/>) will be reported