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

Commit 8440ca39 authored by Svet Ganov's avatar Svet Ganov
Browse files

Relax the parsing code in settings provider.

The practice in the system server is to have lenient parsing code
to avoid the whole system being unusable due to a single XML error.

Change-Id: Idf44031edf5221966f3352ca2f83e284973ab95f
parent 63fa14bd
Loading
Loading
Loading
Loading
+27 −63
Original line number Diff line number Diff line
@@ -416,27 +416,29 @@ final class SettingsState {

    private void parseStateLocked(XmlPullParser parser)
            throws IOException, XmlPullParserException {
        parser.next();
        skipEmptyTextTags(parser);
        expect(parser, XmlPullParser.START_TAG, TAG_SETTINGS);

        mVersion = Integer.parseInt(parser.getAttributeValue(null, ATTR_VERSION));

        parser.next();

        while (parseSettingLocked(parser)) {
            parser.next();
        final int outerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                continue;
            }

        skipEmptyTextTags(parser);
        expect(parser, XmlPullParser.END_TAG, TAG_SETTINGS);
            String tagName = parser.getName();
            if (tagName.equals(TAG_SETTINGS)) {
                parseSettingsLocked(parser);
            }
        }
    }

    private boolean parseSettingLocked(XmlPullParser parser)
    private void parseSettingsLocked(XmlPullParser parser)
            throws IOException, XmlPullParserException {
        skipEmptyTextTags(parser);
        if (!accept(parser, XmlPullParser.START_TAG, TAG_SETTING)) {
            return false;
        final int outerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                continue;
            }

            String id = parser.getAttributeValue(null, ATTR_ID);
@@ -449,47 +451,9 @@ final class SettingsState {
            if (DEBUG_PERSISTENCE) {
                Slog.i(LOG_TAG, "[RESTORED] " + name + "=" + value);
            }

        parser.next();

        skipEmptyTextTags(parser);
        expect(parser, XmlPullParser.END_TAG, TAG_SETTING);

        return true;
    }

    private void expect(XmlPullParser parser, int type, String tag)
            throws IOException, XmlPullParserException {
        if (!accept(parser, type, tag)) {
            throw new XmlPullParserException("Expected event: " + type
                    + " and tag: " + tag + " but got event: " + parser.getEventType()
                    + " and tag:" + parser.getName());
        }
    }

    private void skipEmptyTextTags(XmlPullParser parser)
            throws IOException, XmlPullParserException {
        while (accept(parser, XmlPullParser.TEXT, null)
                && parser.isWhitespace()) {
            parser.next();
        }
    }

    private boolean accept(XmlPullParser parser, int type, String tag)
            throws IOException, XmlPullParserException {
        if (parser.getEventType() != type) {
            return false;
        }
        if (tag != null) {
            if (!tag.equals(parser.getName())) {
                return false;
            }
        } else if (parser.getName() != null) {
            return false;
        }
        return true;
    }

    private final class MyHandler extends Handler {
        public static final int MSG_PERSIST_SETTINGS = 1;