Loading core/java/android/net/Uri.java +19 −17 Original line number Diff line number Diff line Loading @@ -874,11 +874,10 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } static Uri readFrom(Parcel parcel) { final StringUri stringUri = new StringUri(parcel.readString8()); return new OpaqueUri( stringUri.parseScheme(), stringUri.getSsp(), stringUri.getFragmentPart() parcel.readString8(), Part.readFrom(parcel), Part.readFrom(parcel) ); } Loading @@ -888,7 +887,9 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); parcel.writeString8(toString()); parcel.writeString8(scheme); ssp.writeTo(parcel); fragment.writeTo(parcel); } public boolean isHierarchical() { Loading Loading @@ -1187,25 +1188,22 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { Part query, Part fragment) { this.scheme = scheme; this.authority = Part.nonNull(authority); this.path = generatePath(path); this.path = path == null ? PathPart.NULL : path; this.query = Part.nonNull(query); this.fragment = Part.nonNull(fragment); } private PathPart generatePath(PathPart originalPath) { static Uri readFrom(Parcel parcel) { final String scheme = parcel.readString8(); final Part authority = Part.readFrom(parcel); // 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 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()); 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); } public int describeContents() { Loading @@ -1214,7 +1212,11 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); parcel.writeString8(toString()); parcel.writeString8(scheme); authority.writeTo(parcel); path.writeTo(parcel); query.writeTo(parcel); fragment.writeTo(parcel); } public boolean isHierarchical() { Loading core/tests/coretests/src/android/net/UriTest.java +56 −60 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ 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; Loading Loading @@ -850,90 +852,84 @@ public class UriTest extends TestCase { return (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null); } private Uri buildUriFromParts(boolean argumentsEncoded, /** 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, String scheme, String authority, String path, String query, String fragment) { 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); // 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(); } return builder.build(); } public void testUnparcelMalformedPath() { // Regression tests for b/171966843. // Test cases with arguments encoded (covering testing `scheme` * `authority` options). Uri uri0 = buildUriFromParts(true, "https", "google.com", "@evil.com", null, null); Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null); assertEquals("https://google.com/@evil.com", uri0.toString()); Uri uri1 = buildUriFromParts(true, null, "google.com", "@evil.com", "name=spark", "x"); Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x"); assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString()); Uri uri2 = buildUriFromParts(true, "http:", null, "@evil.com", null, null); Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null); assertEquals("http::/@evil.com", uri2.toString()); Uri uri3 = buildUriFromParts(true, null, null, "@evil.com", null, null); Uri uri3 = buildUriFromRawParcel(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 = buildUriFromParts(false, "https", "google.com", "@evil.com", null, null); Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null); assertEquals("https://google.com/%40evil.com", uriA.toString()); Uri uriB = buildUriFromParts(false, null, "google.com", "@evil.com", null, null); Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null); assertEquals("//google.com/%40evil.com", uriB.toString()); Uri uriC = buildUriFromParts(false, "http:", null, "@evil.com", null, null); Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null); assertEquals("http::/%40evil.com", uriC.toString()); Uri uriD = buildUriFromParts(false, null, null, "@evil.com", "name=spark", "y"); Uri uriD = buildUriFromRawParcel(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"); Loading Loading
core/java/android/net/Uri.java +19 −17 Original line number Diff line number Diff line Loading @@ -874,11 +874,10 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } static Uri readFrom(Parcel parcel) { final StringUri stringUri = new StringUri(parcel.readString8()); return new OpaqueUri( stringUri.parseScheme(), stringUri.getSsp(), stringUri.getFragmentPart() parcel.readString8(), Part.readFrom(parcel), Part.readFrom(parcel) ); } Loading @@ -888,7 +887,9 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); parcel.writeString8(toString()); parcel.writeString8(scheme); ssp.writeTo(parcel); fragment.writeTo(parcel); } public boolean isHierarchical() { Loading Loading @@ -1187,25 +1188,22 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { Part query, Part fragment) { this.scheme = scheme; this.authority = Part.nonNull(authority); this.path = generatePath(path); this.path = path == null ? PathPart.NULL : path; this.query = Part.nonNull(query); this.fragment = Part.nonNull(fragment); } private PathPart generatePath(PathPart originalPath) { static Uri readFrom(Parcel parcel) { final String scheme = parcel.readString8(); final Part authority = Part.readFrom(parcel); // 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 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()); 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); } public int describeContents() { Loading @@ -1214,7 +1212,11 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(TYPE_ID); parcel.writeString8(toString()); parcel.writeString8(scheme); authority.writeTo(parcel); path.writeTo(parcel); query.writeTo(parcel); fragment.writeTo(parcel); } public boolean isHierarchical() { Loading
core/tests/coretests/src/android/net/UriTest.java +56 −60 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ 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; Loading Loading @@ -850,90 +852,84 @@ public class UriTest extends TestCase { return (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null); } private Uri buildUriFromParts(boolean argumentsEncoded, /** 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, String scheme, String authority, String path, String query, String fragment) { 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); // 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(); } return builder.build(); } public void testUnparcelMalformedPath() { // Regression tests for b/171966843. // Test cases with arguments encoded (covering testing `scheme` * `authority` options). Uri uri0 = buildUriFromParts(true, "https", "google.com", "@evil.com", null, null); Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null); assertEquals("https://google.com/@evil.com", uri0.toString()); Uri uri1 = buildUriFromParts(true, null, "google.com", "@evil.com", "name=spark", "x"); Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x"); assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString()); Uri uri2 = buildUriFromParts(true, "http:", null, "@evil.com", null, null); Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null); assertEquals("http::/@evil.com", uri2.toString()); Uri uri3 = buildUriFromParts(true, null, null, "@evil.com", null, null); Uri uri3 = buildUriFromRawParcel(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 = buildUriFromParts(false, "https", "google.com", "@evil.com", null, null); Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null); assertEquals("https://google.com/%40evil.com", uriA.toString()); Uri uriB = buildUriFromParts(false, null, "google.com", "@evil.com", null, null); Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null); assertEquals("//google.com/%40evil.com", uriB.toString()); Uri uriC = buildUriFromParts(false, "http:", null, "@evil.com", null, null); Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null); assertEquals("http::/%40evil.com", uriC.toString()); Uri uriD = buildUriFromParts(false, null, null, "@evil.com", "name=spark", "y"); Uri uriD = buildUriFromRawParcel(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"); Loading