summaryrefslogtreecommitdiffstats
path: root/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java')
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java40
1 files changed, 28 insertions, 12 deletions
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 942d32d..83937fa 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -60,6 +60,11 @@ public class SettingsProvider extends ContentProvider {
private static final SettingsCache sSystemCache = new SettingsCache();
private static final SettingsCache sSecureCache = new SettingsCache();
+ // Over this size we don't reject loading or saving settings but
+ // we do consider them broken/malicious and don't keep them in
+ // memory at least:
+ private static final int MAX_CACHE_ENTRY_SIZE = 500;
+
private static final Bundle NULL_SETTING = Bundle.forPair("value", null);
protected DatabaseHelper mOpenHelper;
@@ -264,10 +269,7 @@ public class SettingsProvider extends ContentProvider {
null, null, null, null);
if (cursor != null && cursor.getCount() == 1) {
cursor.moveToFirst();
- String value = cursor.getString(0);
- Bundle bundle = (value == null) ? NULL_SETTING : Bundle.forPair("value", value);
- cache.putIfAbsentLocked(key, bundle);
- return bundle;
+ return cache.putIfAbsent(key, cursor.getString(0));
}
} catch (SQLiteException e) {
Log.w(TAG, "settings lookup error", e);
@@ -275,7 +277,7 @@ public class SettingsProvider extends ContentProvider {
} finally {
if (cursor != null) cursor.close();
}
- cache.putIfAbsentLocked(key, NULL_SETTING);
+ cache.putIfAbsent(key, null);
return NULL_SETTING;
}
@@ -592,6 +594,7 @@ public class SettingsProvider extends ContentProvider {
* database.
*/
private static final class SettingsCache extends LinkedHashMap<String, Bundle> {
+
public SettingsCache() {
super(MAX_CACHE_ENTRIES, 0.75f /* load factor */, true /* access ordered */);
}
@@ -601,14 +604,23 @@ public class SettingsProvider extends ContentProvider {
return size() > MAX_CACHE_ENTRIES;
}
- public void putIfAbsentLocked(String key, Bundle value) {
- synchronized (this) {
- if (containsKey(key)) {
- // Lost a race.
- return;
+ /**
+ * Atomic cache population, conditional on size of value and if
+ * we lost a race.
+ *
+ * @returns a Bundle to send back to the client from call(), even
+ * if we lost the race.
+ */
+ public Bundle putIfAbsent(String key, String value) {
+ Bundle bundle = (value == null) ? NULL_SETTING : Bundle.forPair("value", value);
+ if (value == null || value.length() <= MAX_CACHE_ENTRY_SIZE) {
+ synchronized (this) {
+ if (!containsKey(key)) {
+ put(key, bundle);
+ }
}
- put(key, value);
}
+ return bundle;
}
public static SettingsCache forTable(String tableName) {
@@ -635,7 +647,11 @@ public class SettingsProvider extends ContentProvider {
}
String value = contentValues.getAsString(Settings.NameValueTable.VALUE);
synchronized (cache) {
- cache.put(name, Bundle.forPair(Settings.NameValueTable.VALUE, value));
+ if (value == null || value.length() <= MAX_CACHE_ENTRY_SIZE) {
+ cache.put(name, Bundle.forPair(Settings.NameValueTable.VALUE, value));
+ } else {
+ cache.remove(name);
+ }
}
}