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

Commit b797729b authored by Seigo Nonaka's avatar Seigo Nonaka Committed by Android (Google) Code Review
Browse files

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

parents 41a214c2 0c629dde
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;
            }
        }
    }