Skip to content
Snippets Groups Projects
Commit 01aac2c5 authored by Peter Li's avatar Peter Li Committed by Automerger Merge Worker
Browse files

Merge "Add the protection to avoid data overflow in BinaryXmlSerializer.java"...

Merge "Add the protection to avoid data overflow in BinaryXmlSerializer.java" into sc-dev am: 039660c4 am: 20643002 am: 0b21dd3c am: 56703728

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/27416928



Change-Id: I99fd45ce2bd3f9d5cc4d00c33b204fb1e46bf5f0
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents adbb6b6d 56703728
No related branches found
No related tags found
No related merge requests found
...@@ -97,6 +97,8 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer { ...@@ -97,6 +97,8 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer {
*/ */
private static final int BUFFER_SIZE = 32_768; private static final int BUFFER_SIZE = 32_768;
private static final int MAX_UNSIGNED_SHORT = 65_535;
private FastDataOutput mOut; private FastDataOutput mOut;
/** /**
...@@ -226,6 +228,10 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer { ...@@ -226,6 +228,10 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer {
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
mOut.writeByte(ATTRIBUTE | TYPE_BYTES_HEX); mOut.writeByte(ATTRIBUTE | TYPE_BYTES_HEX);
mOut.writeInternedUTF(name); mOut.writeInternedUTF(name);
if (value.length > MAX_UNSIGNED_SHORT) {
throw new IOException("attributeBytesHex: input size (" + value.length
+ ") exceeds maximum allowed size (" + MAX_UNSIGNED_SHORT + ")");
}
mOut.writeShort(value.length); mOut.writeShort(value.length);
mOut.write(value); mOut.write(value);
return this; return this;
...@@ -237,6 +243,10 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer { ...@@ -237,6 +243,10 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer {
if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); if (namespace != null && !namespace.isEmpty()) throw illegalNamespace();
mOut.writeByte(ATTRIBUTE | TYPE_BYTES_BASE64); mOut.writeByte(ATTRIBUTE | TYPE_BYTES_BASE64);
mOut.writeInternedUTF(name); mOut.writeInternedUTF(name);
if (value.length > MAX_UNSIGNED_SHORT) {
throw new IOException("attributeBytesBase64: input size (" + value.length
+ ") exceeds maximum allowed size (" + MAX_UNSIGNED_SHORT + ")");
}
mOut.writeShort(value.length); mOut.writeShort(value.length);
mOut.write(value); mOut.write(value);
return this; return this;
......
...@@ -24,6 +24,8 @@ import static android.util.XmlTest.doVerifyRead; ...@@ -24,6 +24,8 @@ import static android.util.XmlTest.doVerifyRead;
import static android.util.XmlTest.doVerifyWrite; import static android.util.XmlTest.doVerifyWrite;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
import static org.xmlpull.v1.XmlPullParser.START_TAG; import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.os.PersistableBundle; import android.os.PersistableBundle;
...@@ -38,12 +40,15 @@ import java.io.ByteArrayOutputStream; ...@@ -38,12 +40,15 @@ import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class BinaryXmlTest { public class BinaryXmlTest {
private static final int MAX_UNSIGNED_SHORT = 65_535;
/** /**
* Verify that we can write and read large numbers of interned * Verify that we can write and read large numbers of interned
* {@link String} values. * {@link String} values.
...@@ -167,4 +172,49 @@ public class BinaryXmlTest { ...@@ -167,4 +172,49 @@ public class BinaryXmlTest {
} }
} }
} }
@Test
public void testAttributeBytes_BinaryDataOverflow() throws Exception {
final TypedXmlSerializer out = Xml.newBinarySerializer();
final ByteArrayOutputStream os = new ByteArrayOutputStream();
out.setOutput(os, StandardCharsets.UTF_8.name());
final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT + 1];
assertThrows(IOException.class,
() -> out.attributeBytesHex(/* namespace */ null, /* name */ "attributeBytesHex",
testBytes));
assertThrows(IOException.class,
() -> out.attributeBytesBase64(/* namespace */ null, /* name */
"attributeBytesBase64", testBytes));
}
@Test
public void testAttributeBytesHex_MaximumBinaryData() throws Exception {
final TypedXmlSerializer out = Xml.newBinarySerializer();
final ByteArrayOutputStream os = new ByteArrayOutputStream();
out.setOutput(os, StandardCharsets.UTF_8.name());
final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT];
try {
out.attributeBytesHex(/* namespace */ null, /* name */ "attributeBytesHex", testBytes);
} catch (Exception e) {
fail("testAttributeBytesHex fails with exception: " + e.toString());
}
}
@Test
public void testAttributeBytesBase64_MaximumBinaryData() throws Exception {
final TypedXmlSerializer out = Xml.newBinarySerializer();
final ByteArrayOutputStream os = new ByteArrayOutputStream();
out.setOutput(os, StandardCharsets.UTF_8.name());
final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT];
try {
out.attributeBytesBase64(/* namespace */ null, /* name */ "attributeBytesBase64",
testBytes);
} catch (Exception e) {
fail("testAttributeBytesBase64 fails with exception: " + e.toString());
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment