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

Unverified Commit f01abdb2 authored by Michael Bestas's avatar Michael Bestas Committed by Michael Bestas
Browse files

Reapply "Update parcling logic for Uris."

This reverts commit e4da571363e2adb1ccbb0a4b21606f921bb3cd90.

Reason for revert: This is now present in QPR2

Change-Id: I78393b6e4b246ccfc7516f9bd46ecb3bc9f01997
parent 7510f316
Loading
Loading
Loading
Loading
+17 −19
Original line number Diff line number Diff line
@@ -882,10 +882,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()
            );
        }

@@ -895,9 +896,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() {
@@ -1196,22 +1195,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() {
@@ -1220,11 +1222,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() {
+60 −56
Original line number Diff line number Diff line
@@ -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;
@@ -869,84 +867,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");