From 6771d73703d35f2b28b8602dcbbed88fdffb9a0b Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Thu, 14 Jul 2016 12:58:40 -0700 Subject: [PATCH] Don't accept resource references in string fields Detect it when a developer accidentally uses @string/... in string fields and log an error rather than publishing shortcuts with wrong values. Bug 30140672 Change-Id: I98a60afd7f52282019a94a7a8c30a85ea4c7806b --- .../com/android/server/pm/ShortcutParser.java | 18 ++++++++++--- .../res/xml/shortcut_error_3.xml | 6 +++++ .../server/pm/ShortcutManagerTest1.java | 27 ++++++++++++------- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/services/core/java/com/android/server/pm/ShortcutParser.java b/services/core/java/com/android/server/pm/ShortcutParser.java index 0762c0b21678b..3f302d67acf65 100644 --- a/services/core/java/com/android/server/pm/ShortcutParser.java +++ b/services/core/java/com/android/server/pm/ShortcutParser.java @@ -29,6 +29,7 @@ import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; import android.util.Slog; +import android.util.TypedValue; import android.util.Xml; import com.android.internal.R; @@ -260,7 +261,12 @@ public class ShortcutParser { final TypedArray sa = service.mContext.getResources().obtainAttributes(attrs, R.styleable.ShortcutCategories); try { - return sa.getString(R.styleable.ShortcutCategories_name); + if (sa.getType(R.styleable.ShortcutCategories_name) == TypedValue.TYPE_STRING) { + return sa.getNonResourceString(R.styleable.ShortcutCategories_name); + } else { + Log.w(TAG, "android:name for shortcut category must be string literal."); + return null; + } } finally { sa.recycle(); } @@ -272,7 +278,11 @@ public class ShortcutParser { final TypedArray sa = service.mContext.getResources().obtainAttributes(attrs, R.styleable.Shortcut); try { - final String id = sa.getString(R.styleable.Shortcut_shortcutId); + if (sa.getType(R.styleable.Shortcut_shortcutId) != TypedValue.TYPE_STRING) { + Log.w(TAG, "android:shortcutId must be string literal. activity=" + activity); + return null; + } + final String id = sa.getNonResourceString(R.styleable.Shortcut_shortcutId); final boolean enabled = sa.getBoolean(R.styleable.Shortcut_enabled, true); final int iconResId = sa.getResourceId(R.styleable.Shortcut_icon, 0); final int titleResId = sa.getResourceId(R.styleable.Shortcut_shortcutShortLabel, 0); @@ -281,11 +291,11 @@ public class ShortcutParser { R.styleable.Shortcut_shortcutDisabledMessage, 0); if (TextUtils.isEmpty(id)) { - Slog.w(TAG, "Shortcut ID must be provided. activity=" + activity); + Log.w(TAG, "android:shortcutId must be provided. activity=" + activity); return null; } if (titleResId == 0) { - Slog.w(TAG, "Shortcut title must be provided. activity=" + activity); + Log.w(TAG, "android:shortcutShortLabel must be provided. activity=" + activity); return null; } diff --git a/services/tests/servicestests/res/xml/shortcut_error_3.xml b/services/tests/servicestests/res/xml/shortcut_error_3.xml index a7b9b84a9e3cc..24ee024f64a44 100644 --- a/services/tests/servicestests/res/xml/shortcut_error_3.xml +++ b/services/tests/servicestests/res/xml/shortcut_error_3.xml @@ -18,6 +18,10 @@ android:shortcutId="manifest-shortcut-3" android:shortcutShortLabel="@string/shortcut_title1" /> + + + diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index bf6c2ff97bec1..ae2d63213dffa 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -5856,9 +5856,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Only the valid one is published. runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled( - mManager.getManifestShortcuts()))), - "x1"); + assertWith(getCallerShortcuts()) + .areAllManifest() + .areAllImmutable() + .areAllEnabled() + .haveIds("x1"); }); // Package 1 updated, which has one valid manifest shortcut and one invalid. @@ -5871,9 +5873,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Only the valid one is published. runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled( - mManager.getManifestShortcuts()))), - "x2"); + assertWith(getCallerShortcuts()) + .areAllManifest() + .areAllImmutable() + .areAllEnabled() + .haveIds("x2"); }); // Package 1 updated, which has one valid manifest shortcut and one invalid. @@ -5886,9 +5890,14 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Only the valid one is published. runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled( - mManager.getManifestShortcuts()))), - "x3"); + assertWith(getCallerShortcuts()) + .areAllManifest() + .areAllImmutable() + .areAllEnabled() + .haveIds("x3") + .forShortcutWithId("x3", si -> { + assertEquals(set("cat2"), si.getCategories()); + }); }); }