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

Commit 5bf28b0e authored by Seigo Nonaka's avatar Seigo Nonaka Committed by Automerger Merge Worker
Browse files

Merge "Avoid infinite loop for invalid XML format" into sc-dev am: b797729b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13695988

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ic6fe44b69ec612b29c1bb7356a138846235ca2b4
parents f3289c70 b797729b
Loading
Loading
Loading
Loading
+108 −1
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import static android.text.FontConfig.FontFamily.VARIANT_ELEGANT;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import static junit.framework.Assert.fail;

import android.graphics.fonts.FontStyle;
import android.os.LocaleList;
import android.text.FontConfig;
@@ -44,6 +46,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

@@ -221,9 +224,113 @@ public final class FontListParserTest {
                .that(readFamily(serialized)).isEqualTo(expected);
    }

    @Test
    public void invalidXml_unpaired_family() throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?>"
                + "<familyset>"
                + "  <family name='sans-serif'>"
                + "    <font index='0'>test.ttc</font>"
                + "</familyset>";

        try (InputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) {
            FontListParser.parse(is);
            fail();
        } catch (IOException | XmlPullParserException e) {
            // pass
        }
    }

    @Test
    public void invalidXml_unpaired_font() throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?>"
                + "<familyset>"
                + "  <family name='sans-serif'>"
                + "    <font index='0'>test.ttc"
                + "  </family>"
                + "</familyset>";

        try (InputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) {
            FontListParser.parse(is);
            fail();
        } catch (IOException | XmlPullParserException e) {
            // pass
        }
    }

    @Test
    public void invalidXml_unpaired_axis() throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?>"
                + "<familyset>"
                + "  <family name='sans-serif'>"
                + "    <font index='0'>test.ttc"
                + "        <axis tag=\"wght\" styleValue=\"0\" >"
                + "    </font>"
                + "  </family>"
                + "</familyset>";

        try (InputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) {
            FontListParser.parse(is);
            fail();
        } catch (IOException | XmlPullParserException e) {
            // pass
        }
    }

    @Test
    public void invalidXml_unclosed_family() throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?>"
                + "<familyset>"
                + "  <family name='sans-serif'"
                + "    <font index='0'>test.ttc</font>"
                + "  </family>"
                + "</familyset>";

        try (InputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) {
            FontListParser.parse(is);
            fail();
        } catch (IOException | XmlPullParserException e) {
            // pass
        }
    }

    @Test
    public void invalidXml_unclosed_font() throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?>"
                + "<familyset>"
                + "  <family name='sans-serif'>"
                + "    <font index='0'"
                + "  </family>"
                + "</familyset>";

        try (InputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) {
            FontListParser.parse(is);
            fail();
        } catch (IOException | XmlPullParserException e) {
            // pass
        }
    }

    @Test
    public void invalidXml_unclosed_axis() throws Exception {
        String xml = "<?xml version='1.0' encoding='UTF-8'?>"
                + "<familyset>"
                + "  <family name='sans-serif'>"
                + "    <font index='0'>test.ttc"
                + "        <axis tag=\"wght\" styleValue=\"0\""
                + "    </font>"
                + "  </family>"
                + "</familyset>";

        try (InputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) {
            FontListParser.parse(is);
            fail();
        } catch (IOException | XmlPullParserException e) {
            // pass
        }
    }

    private FontConfig.FontFamily readFamily(String xml)
            throws IOException, XmlPullParserException {
        StandardCharsets.UTF_8.name();
        ByteArrayInputStream buffer = new ByteArrayInputStream(
                xml.getBytes(StandardCharsets.UTF_8));
        XmlPullParser parser = Xml.newPullParser();
+11 −3
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ public class FontListParser {
                customization.getAdditionalNamedFamilies();

        parser.require(XmlPullParser.START_TAG, null, "familyset");
        while (parser.next() != XmlPullParser.END_TAG) {
        while (keepReading(parser)) {
            if (parser.getEventType() != XmlPullParser.START_TAG) continue;
            String tag = parser.getName();
            if (tag.equals("family")) {
@@ -158,6 +158,12 @@ public class FontListParser {
        return new FontConfig(families, aliases, lastModifiedDate, configVersion);
    }

    private static boolean keepReading(XmlPullParser parser)
            throws XmlPullParserException, IOException {
        int next = parser.next();
        return next != XmlPullParser.END_TAG && next != XmlPullParser.END_DOCUMENT;
    }

    /**
     * Read family tag in fonts.xml or oem_customization.xml
     */
@@ -168,7 +174,7 @@ public class FontListParser {
        final String lang = parser.getAttributeValue("", "lang");
        final String variant = parser.getAttributeValue(null, "variant");
        final List<FontConfig.Font> fonts = new ArrayList<>();
        while (parser.next() != XmlPullParser.END_TAG) {
        while (keepReading(parser)) {
            if (parser.getEventType() != XmlPullParser.START_TAG) continue;
            final String tag = parser.getName();
            if (tag.equals(TAG_FONT)) {
@@ -232,7 +238,7 @@ public class FontListParser {
        boolean isItalic = STYLE_ITALIC.equals(parser.getAttributeValue(null, ATTR_STYLE));
        String fallbackFor = parser.getAttributeValue(null, ATTR_FALLBACK_FOR);
        StringBuilder filename = new StringBuilder();
        while (parser.next() != XmlPullParser.END_TAG) {
        while (keepReading(parser)) {
            if (parser.getEventType() == XmlPullParser.TEXT) {
                filename.append(parser.getText());
            }
@@ -359,6 +365,8 @@ public class FontListParser {
                case XmlPullParser.END_TAG:
                    depth--;
                    break;
                case XmlPullParser.END_DOCUMENT:
                    return;
            }
        }
    }