Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d926f4f2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Update parcling logic for Uris."" into rvc-dev

parents 447216ec a47503c8
Loading
Loading
Loading
Loading
+19 −17
Original line number Diff line number Diff line
@@ -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() {
+56 −60
Original line number Diff line number Diff line
@@ -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");