diff options
author | Varun Shah <varunshah@google.com> | 2023-07-12 18:45:00 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-07-12 18:45:00 +0000 |
commit | adc6fe9aa439e3cb7b83058fac4ac58fa90cad1e (patch) | |
tree | b8392a99399bd676a9b4c9d97c8ade01c20d7df3 | |
parent | 1b1950ac884c01885dd183ee543cde2c739d5fd7 (diff) | |
parent | cdb758450b0dbc2398b3facadf8486ef98f2c583 (diff) | |
download | base-adc6fe9aa439e3cb7b83058fac4ac58fa90cad1e.tar.gz |
Merge "Update parcling logic for Uris." into rvc-dev am: cdb758450b
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23835332
Change-Id: Ib906252b0b2b8e1ca91bd80ef7183e450a19428e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | core/java/android/net/Uri.java | 36 | ||||
-rw-r--r-- | core/tests/coretests/src/android/net/UriTest.java | 116 |
2 files changed, 77 insertions, 75 deletions
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index 84fc4f78edc4..05e9e0df9033 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -874,10 +874,11 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } static Uri readFrom(Parcel parcel) { + final StringUri stringUri = new StringUri(parcel.readString8()); return new OpaqueUri( - parcel.readString8(), - Part.readFrom(parcel), - Part.readFrom(parcel) + stringUri.parseScheme(), + stringUri.getSsp(), + stringUri.getFragmentPart() ); } @@ -887,9 +888,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); - parcel.writeString8(scheme); - ssp.writeTo(parcel); - fragment.writeTo(parcel); + parcel.writeString8(toString()); } public boolean isHierarchical() { @@ -1188,22 +1187,25 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { Part query, Part fragment) { this.scheme = scheme; this.authority = Part.nonNull(authority); - this.path = path == null ? PathPart.NULL : path; + this.path = generatePath(path); this.query = Part.nonNull(query); this.fragment = Part.nonNull(fragment); } - static Uri readFrom(Parcel parcel) { - final String scheme = parcel.readString8(); - final Part authority = Part.readFrom(parcel); + private PathPart generatePath(PathPart originalPath) { // In RFC3986 the path should be determined based on whether there is a scheme or // authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3). final boolean hasSchemeOrAuthority = (scheme != null && scheme.length() > 0) || !authority.isEmpty(); - final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel); - final Part query = Part.readFrom(parcel); - final Part fragment = Part.readFrom(parcel); - return new HierarchicalUri(scheme, authority, path, query, fragment); + final PathPart newPath = hasSchemeOrAuthority ? PathPart.makeAbsolute(originalPath) + : originalPath; + return newPath == null ? PathPart.NULL : newPath; + } + + static Uri readFrom(Parcel parcel) { + final StringUri stringUri = new StringUri(parcel.readString8()); + return new HierarchicalUri(stringUri.getScheme(), stringUri.getAuthorityPart(), + stringUri.getPathPart(), stringUri.getQueryPart(), stringUri.getFragmentPart()); } public int describeContents() { @@ -1212,11 +1214,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); - parcel.writeString8(scheme); - authority.writeTo(parcel); - path.writeTo(parcel); - query.writeTo(parcel); - fragment.writeTo(parcel); + parcel.writeString8(toString()); } public boolean isHierarchical() { diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java index 670aefd21d36..5e9ce9801bb5 100644 --- a/core/tests/coretests/src/android/net/UriTest.java +++ b/core/tests/coretests/src/android/net/UriTest.java @@ -25,8 +25,6 @@ import junit.framework.TestCase; import java.io.File; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Arrays; import java.util.Iterator; import java.util.List; @@ -852,84 +850,90 @@ public class UriTest extends TestCase { return (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null); } - /** Attempting to unparcel a legacy parcel format of Uri.{,Path}Part should fail. */ - public void testUnparcelLegacyPart_fails() throws Exception { - assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$Part")); - assertUnparcelLegacyPart_fails(Class.forName("android.net.Uri$PathPart")); - } - - private static void assertUnparcelLegacyPart_fails(Class partClass) throws Exception { - Parcel parcel = Parcel.obtain(); - parcel.writeInt(0 /* BOTH */); - parcel.writeString("encoded"); - parcel.writeString("decoded"); - parcel.setDataPosition(0); - - Method readFromMethod = partClass.getDeclaredMethod("readFrom", Parcel.class); - readFromMethod.setAccessible(true); - try { - readFromMethod.invoke(null, parcel); - fail(); - } catch (InvocationTargetException expected) { - Throwable targetException = expected.getTargetException(); - // Check that the exception was thrown for the correct reason. - assertEquals("Unknown representation: 0", targetException.getMessage()); - } finally { - parcel.recycle(); - } - } - - private Uri buildUriFromRawParcel(boolean argumentsEncoded, + private Uri buildUriFromParts(boolean argumentsEncoded, String scheme, String authority, String path, String query, String fragment) { - // Representation value (from AbstractPart.REPRESENTATION_{ENCODED,DECODED}). - final int representation = argumentsEncoded ? 1 : 2; - Parcel parcel = Parcel.obtain(); - try { - parcel.writeInt(3); // hierarchical - parcel.writeString8(scheme); - parcel.writeInt(representation); - parcel.writeString8(authority); - parcel.writeInt(representation); - parcel.writeString8(path); - parcel.writeInt(representation); - parcel.writeString8(query); - parcel.writeInt(representation); - parcel.writeString8(fragment); - parcel.setDataPosition(0); - return Uri.CREATOR.createFromParcel(parcel); - } finally { - parcel.recycle(); + final Uri.Builder builder = new Uri.Builder(); + builder.scheme(scheme); + if (argumentsEncoded) { + builder.encodedAuthority(authority); + builder.encodedPath(path); + builder.encodedQuery(query); + builder.encodedFragment(fragment); + } else { + builder.authority(authority); + builder.path(path); + builder.query(query); + builder.fragment(fragment); } + return builder.build(); } public void testUnparcelMalformedPath() { // Regression tests for b/171966843. // Test cases with arguments encoded (covering testing `scheme` * `authority` options). - Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null); + Uri uri0 = buildUriFromParts(true, "https", "google.com", "@evil.com", null, null); assertEquals("https://google.com/@evil.com", uri0.toString()); - Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x"); + Uri uri1 = buildUriFromParts(true, null, "google.com", "@evil.com", "name=spark", "x"); assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString()); - Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null); + Uri uri2 = buildUriFromParts(true, "http:", null, "@evil.com", null, null); assertEquals("http::/@evil.com", uri2.toString()); - Uri uri3 = buildUriFromRawParcel(true, null, null, "@evil.com", null, null); + Uri uri3 = buildUriFromParts(true, null, null, "@evil.com", null, null); assertEquals("@evil.com", uri3.toString()); // Test cases with arguments not encoded (covering testing `scheme` * `authority` options). - Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null); + Uri uriA = buildUriFromParts(false, "https", "google.com", "@evil.com", null, null); assertEquals("https://google.com/%40evil.com", uriA.toString()); - Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null); + Uri uriB = buildUriFromParts(false, null, "google.com", "@evil.com", null, null); assertEquals("//google.com/%40evil.com", uriB.toString()); - Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null); + Uri uriC = buildUriFromParts(false, "http:", null, "@evil.com", null, null); assertEquals("http::/%40evil.com", uriC.toString()); - Uri uriD = buildUriFromRawParcel(false, null, null, "@evil.com", "name=spark", "y"); + Uri uriD = buildUriFromParts(false, null, null, "@evil.com", "name=spark", "y"); assertEquals("%40evil.com?name%3Dspark#y", uriD.toString()); } + public void testParsedUriFromStringEquality() { + Uri uri = buildUriFromParts( + true, "https", "google.com", "@evil.com", null, null); + assertEquals(uri, Uri.parse(uri.toString())); + Uri uri2 = buildUriFromParts( + true, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null); + assertEquals(uri2, Uri.parse(uri2.toString())); + Uri uri3 = buildUriFromParts( + false, "content://evil.authority?foo=", "safe.authority", "@evil.com", null, null); + assertEquals(uri3, Uri.parse(uri3.toString())); + } + + public void testParceledUrisAreEqual() { + Uri opaqueUri = Uri.fromParts("fake://uri#", "ssp", "fragment"); + Parcel parcel = Parcel.obtain(); + try { + opaqueUri.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel); + Uri parsedUri = Uri.parse(postParcelUri.toString()); + assertEquals(parsedUri.getScheme(), postParcelUri.getScheme()); + } finally { + parcel.recycle(); + } + + Uri hierarchicalUri = new Uri.Builder().scheme("fake://uri#").authority("auth").build(); + parcel = Parcel.obtain(); + try { + hierarchicalUri.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + Uri postParcelUri = Uri.CREATOR.createFromParcel(parcel); + Uri parsedUri = Uri.parse(postParcelUri.toString()); + assertEquals(parsedUri.getScheme(), postParcelUri.getScheme()); + } finally { + parcel.recycle(); + } + } + public void testToSafeString() { checkToSafeString("tel:xxxxxx", "tel:Google"); checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890"); |