diff options
| -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, 75 insertions, 77 deletions
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java index 05e9e0df9033..84fc4f78edc4 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -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)              );          } @@ -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() { @@ -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() { @@ -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() { diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java index 5e9ce9801bb5..670aefd21d36 100644 --- a/core/tests/coretests/src/android/net/UriTest.java +++ b/core/tests/coretests/src/android/net/UriTest.java @@ -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; @@ -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");  |