diff options
author | Jeff Sharkey <jsharkey@android.com> | 2020-10-27 22:58:30 -0600 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2020-11-13 14:48:28 -0700 |
commit | ca3ea93171a4a46d42298a75f4139e8e660d303f (patch) | |
tree | c9d6e45fc5d21d69196871731f815b54391434be /errorprone/tests | |
parent | 82fe62465b1b785d70eae16b028f711455caa62f (diff) |
Progress towards efficient XML serialization.
Related changes are introducing new TypedXmlSerializer and
TypedXmlPullParser interfaces which offer efficient access to
primitive attributes, and this Error Prone detector helps identify
code that should shift to using those new interfaces.
Bug: 171832118
Test: atest error_prone_android_framework_test
Change-Id: Ic3ca6b96d2b056e6178e407af886bb925a3471c8
Diffstat (limited to 'errorprone/tests')
6 files changed, 451 insertions, 0 deletions
diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/EfficientXmlCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/EfficientXmlCheckerTest.java new file mode 100644 index 000000000000..084fb255ed7b --- /dev/null +++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/EfficientXmlCheckerTest.java @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.errorprone.bugpatterns.android; + +import com.google.errorprone.CompilationTestHelper; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class EfficientXmlCheckerTest { + private CompilationTestHelper compilationHelper; + + @Before + public void setUp() { + compilationHelper = CompilationTestHelper.newInstance( + EfficientXmlChecker.class, getClass()); + } + + @Test + public void testCtor() { + compilationHelper + .addSourceFile("/android/util/Xml.java") + .addSourceFile("/com/android/internal/util/FastXmlSerializer.java") + .addSourceLines("Example.java", + "import android.util.Xml;", + "import com.android.internal.util.FastXmlSerializer;", + "public class Example {", + " public void writer() throws Exception {", + " // BUG: Diagnostic contains:", + " Xml.newSerializer();", + " // BUG: Diagnostic contains:", + " new FastXmlSerializer();", + " }", + " public void reader() throws Exception {", + " // BUG: Diagnostic contains:", + " Xml.newPullParser();", + " }", + "}") + .doTest(); + } + + @Test + public void testWrite() { + compilationHelper + .addSourceLines("Example.java", + "import org.xmlpull.v1.XmlSerializer;", + "public class Example {", + " public void typical(XmlSerializer out) throws Exception {", + " out.attribute(null, null, null);", + " out.attribute(null, null, \"foo\");", + " out.attribute(null, null, String.valueOf(null));", + " out.attribute(null, null, String.valueOf(\"foo\"));", + " }", + " public void rawBoolean(XmlSerializer out) throws Exception {", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, \"true\");", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, \"false\");", + " }", + " public void toString(XmlSerializer out) throws Exception {", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Integer.toString(42));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Integer.toString(42, 10));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Integer.toString(42, 16));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Integer.toHexString(42));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Long.toString(42L));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Long.toString(42L, 10));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Long.toString(42L, 16));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Long.toHexString(42L));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Float.toString(42f));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Double.toString(42d));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Boolean.toString(true));", + " }", + " public void toStringBoxed(XmlSerializer out) throws Exception {", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Integer.valueOf(42).toString());", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Long.valueOf(42L).toString());", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Float.valueOf(42f).toString());", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Double.valueOf(42d).toString());", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Boolean.valueOf(true).toString());", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, Boolean.TRUE.toString());", + " }", + " public void valueOf(XmlSerializer out) throws Exception {", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(42));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(42L));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(42f));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(42d));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(true));", + " }", + " public void valueOfBoxed(XmlSerializer out) throws Exception {", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(Integer.valueOf(42)));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(Long.valueOf(42L)));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(Float.valueOf(42f)));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(Double.valueOf(42d)));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(Boolean.valueOf(true)));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null, String.valueOf(Boolean.TRUE));", + " }", + "}") + .doTest(); + } + + @Test + public void testWrite_Indirect() { + compilationHelper + .addSourceLines("Example.java", + "import org.xmlpull.v1.XmlSerializer;", + "public class Example {", + " XmlSerializer out;", + " public void argUnknown(String arg) throws Exception {", + " out.attribute(null, null, arg);", + " }", + " public void argNull(String arg) throws Exception {", + " arg = null;", + " out.attribute(null, null, arg);", + " }", + " public void argValueOfNull(String arg) throws Exception {", + " arg = String.valueOf(null);", + " out.attribute(null, null, arg);", + " }", + " public void argToString(String arg) throws Exception {", + " // BUG: Diagnostic contains:", + " arg = Integer.toString(42);", + " out.attribute(null, null, arg);", + " }", + " public void argValueOf(String arg) throws Exception {", + " // BUG: Diagnostic contains:", + " arg = String.valueOf(42);", + " out.attribute(null, null, arg);", + " }", + " public void directToString() throws Exception {", + " // BUG: Diagnostic contains:", + " String arg = Integer.toString(42);", + " out.attribute(null, null, arg);", + " }", + "}") + .doTest(); + } + + @Test + public void testWrite_Bytes() { + compilationHelper + .addSourceFile("/android/util/Base64.java") + .addSourceFile("/libcore/util/HexEncoding.java") + .addSourceFile("/com/android/internal/util/HexDump.java") + .addSourceLines("Example.java", + "import org.xmlpull.v1.XmlSerializer;", + "public class Example {", + " XmlSerializer out;", + " public void bytes(byte[] arg) throws Exception {", + " // BUG: Diagnostic contains:", + " out.attribute(null, null,", + " android.util.Base64.encodeToString(arg, 0));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null,", + " java.util.Base64.getEncoder().encodeToString(arg));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null,", + " libcore.util.HexEncoding.encodeToString(arg));", + " // BUG: Diagnostic contains:", + " out.attribute(null, null,", + " com.android.internal.util.HexDump.toHexString(arg));", + " }", + "}") + .doTest(); + } + + @Test + public void testRead() { + compilationHelper + .addSourceLines("Example.java", + "import org.xmlpull.v1.XmlPullParser;", + "public class Example {", + " public void typical(XmlPullParser in) throws Exception {", + " in.getAttributeValue(null, null);", + " }", + " public void parse(XmlPullParser in) throws Exception {", + " // BUG: Diagnostic contains:", + " Integer.parseInt(in.getAttributeValue(null, null));", + " // BUG: Diagnostic contains:", + " Integer.parseInt(in.getAttributeValue(null, null), 10);", + " // BUG: Diagnostic contains:", + " Integer.parseInt(in.getAttributeValue(null, null), 16);", + " // BUG: Diagnostic contains:", + " Long.parseLong(in.getAttributeValue(null, null));", + " // BUG: Diagnostic contains:", + " Long.parseLong(in.getAttributeValue(null, null), 10);", + " // BUG: Diagnostic contains:", + " Long.parseLong(in.getAttributeValue(null, null), 16);", + " // BUG: Diagnostic contains:", + " Float.parseFloat(in.getAttributeValue(null, null));", + " // BUG: Diagnostic contains:", + " Double.parseDouble(in.getAttributeValue(null, null));", + " // BUG: Diagnostic contains:", + " Boolean.parseBoolean(in.getAttributeValue(null, null));", + " }", + " public void valueOf(XmlPullParser in) throws Exception {", + " // BUG: Diagnostic contains:", + " Integer.valueOf(in.getAttributeValue(null, null));", + " // BUG: Diagnostic contains:", + " Long.valueOf(in.getAttributeValue(null, null));", + " // BUG: Diagnostic contains:", + " Float.valueOf(in.getAttributeValue(null, null));", + " // BUG: Diagnostic contains:", + " Double.valueOf(in.getAttributeValue(null, null));", + " // BUG: Diagnostic contains:", + " Boolean.valueOf(in.getAttributeValue(null, null));", + " }", + "}") + .doTest(); + } + + @Test + public void testRead_Indirect() { + compilationHelper + .addSourceLines("Example.java", + "import org.xmlpull.v1.XmlPullParser;", + "public class Example {", + " public int direct(XmlPullParser in) throws Exception {", + " String arg = in.getAttributeValue(null, null);", + " if (arg != null) {", + " // BUG: Diagnostic contains:", + " return Integer.parseInt(arg);", + " } else {", + " return -1;", + " }", + " }", + " public int indirect(XmlPullParser in, String arg) throws Exception {", + " arg = in.getAttributeValue(null, null);", + " if (arg != null) {", + " // BUG: Diagnostic contains:", + " return Integer.parseInt(arg);", + " } else {", + " return -1;", + " }", + " }", + " public int tryCatch(XmlPullParser in) throws Exception {", + " String arg = in.getAttributeValue(null, null);", + " try {", + " // BUG: Diagnostic contains:", + " return Integer.parseInt(arg);", + " } catch (NumberFormatException e) {", + " return -1;", + " }", + " }", + "}") + .doTest(); + } + + @Test + public void testRead_Bytes() { + compilationHelper + .addSourceFile("/android/util/Base64.java") + .addSourceFile("/libcore/util/HexEncoding.java") + .addSourceFile("/com/android/internal/util/HexDump.java") + .addSourceLines("Example.java", + "import org.xmlpull.v1.XmlPullParser;", + "public class Example {", + " XmlPullParser in;", + " public void bytes() throws Exception {", + " android.util.Base64.decode(", + " // BUG: Diagnostic contains:", + " in.getAttributeValue(null, null), 0);", + " java.util.Base64.getDecoder().decode(", + " // BUG: Diagnostic contains:", + " in.getAttributeValue(null, null));", + " libcore.util.HexEncoding.decode(", + " // BUG: Diagnostic contains:", + " in.getAttributeValue(null, null));", + " com.android.internal.util.HexDump.hexStringToByteArray(", + " // BUG: Diagnostic contains:", + " in.getAttributeValue(null, null));", + " }", + "}") + .doTest(); + } +} diff --git a/errorprone/tests/res/android/util/Base64.java b/errorprone/tests/res/android/util/Base64.java new file mode 100644 index 000000000000..63d80befd750 --- /dev/null +++ b/errorprone/tests/res/android/util/Base64.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 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.util; + +public class Base64 { + public static byte[] decode(String str, int flags) { + throw new UnsupportedOperationException(); + } + + public static String encodeToString(byte[] input, int flags) { + throw new UnsupportedOperationException(); + } +} diff --git a/errorprone/tests/res/android/util/Xml.java b/errorprone/tests/res/android/util/Xml.java new file mode 100644 index 000000000000..0e44d00f4812 --- /dev/null +++ b/errorprone/tests/res/android/util/Xml.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 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.util; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlSerializer; + +public class Xml { + public static XmlPullParser newPullParser() { + throw new UnsupportedOperationException(); + } + + public static XmlSerializer newSerializer() { + throw new UnsupportedOperationException(); + } +} diff --git a/errorprone/tests/res/com/android/internal/util/FastXmlSerializer.java b/errorprone/tests/res/com/android/internal/util/FastXmlSerializer.java new file mode 100644 index 000000000000..83d14a9a3c64 --- /dev/null +++ b/errorprone/tests/res/com/android/internal/util/FastXmlSerializer.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util; + +public class FastXmlSerializer { +} diff --git a/errorprone/tests/res/com/android/internal/util/HexDump.java b/errorprone/tests/res/com/android/internal/util/HexDump.java new file mode 100644 index 000000000000..55d3e50cc7bb --- /dev/null +++ b/errorprone/tests/res/com/android/internal/util/HexDump.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util; + +public class HexDump { + public static String toHexString(byte[] array) { + throw new UnsupportedOperationException(); + } + + public static byte[] hexStringToByteArray(String hexString) { + throw new UnsupportedOperationException(); + } +} diff --git a/errorprone/tests/res/libcore/util/HexEncoding.java b/errorprone/tests/res/libcore/util/HexEncoding.java new file mode 100644 index 000000000000..34bbbaca4c1d --- /dev/null +++ b/errorprone/tests/res/libcore/util/HexEncoding.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 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.util; + +public class HexEncoding { + public static String encodeToString(byte[] data) { + throw new UnsupportedOperationException(); + } + + public static byte[] decode(String encoded) { + throw new UnsupportedOperationException(); + } +} |