summaryrefslogtreecommitdiff
path: root/core/java/android/os/Bundle.java
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2016-03-17 18:54:28 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-03-17 18:54:28 +0000
commit7029a23b381ca40d1661353fdf81333c7bc308d6 (patch)
tree65b7ac2ea08f263f659af1e142a0cfa40e98395a /core/java/android/os/Bundle.java
parent15da999d7dab26b851203158059b89f31de6b73f (diff)
parenta0f6318f44244ec4e916d3abecf157beb4fefc8c (diff)
Merge "Defuse Bundles parsed by the system process." into nyc-dev am: c4b0ade
am: a0f6318 * commit 'a0f6318f44244ec4e916d3abecf157beb4fefc8c': Defuse Bundles parsed by the system process.
Diffstat (limited to 'core/java/android/os/Bundle.java')
-rw-r--r--core/java/android/os/Bundle.java106
1 files changed, 70 insertions, 36 deletions
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index be9566c3e0a0..7ef86f22d86e 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -27,11 +27,17 @@ import java.util.ArrayList;
import java.util.List;
/**
- * A mapping from String values to various Parcelable types.
+ * A mapping from String keys to various {@link Parcelable} values.
*
+ * @see PersistableBundle
*/
public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
+ private static final int FLAG_HAS_FDS = 1 << 8;
+ private static final int FLAG_HAS_FDS_KNOWN = 1 << 9;
+ private static final int FLAG_ALLOW_FDS = 1 << 10;
+
public static final Bundle EMPTY;
+
static final Parcel EMPTY_PARCEL;
static {
@@ -40,15 +46,12 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
EMPTY_PARCEL = BaseBundle.EMPTY_PARCEL;
}
- private boolean mHasFds = false;
- private boolean mFdsKnown = true;
- private boolean mAllowFds = true;
-
/**
* Constructs a new, empty Bundle.
*/
public Bundle() {
super();
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -59,16 +62,18 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
Bundle(Parcel parcelledData) {
super(parcelledData);
-
- mHasFds = mParcelledData.hasFileDescriptors();
- mFdsKnown = true;
+ mFlags = FLAG_HAS_FDS_KNOWN;
+ if (mParcelledData.hasFileDescriptors()) {
+ mFlags |= FLAG_HAS_FDS;
+ }
}
/* package */ Bundle(Parcel parcelledData, int length) {
super(parcelledData, length);
-
- mHasFds = mParcelledData.hasFileDescriptors();
- mFdsKnown = true;
+ mFlags = FLAG_HAS_FDS_KNOWN;
+ if (mParcelledData.hasFileDescriptors()) {
+ mFlags |= FLAG_HAS_FDS;
+ }
}
/**
@@ -80,6 +85,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public Bundle(ClassLoader loader) {
super(loader);
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -90,6 +96,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public Bundle(int capacity) {
super(capacity);
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -100,9 +107,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public Bundle(Bundle b) {
super(b);
-
- mHasFds = b.mHasFds;
- mFdsKnown = b.mFdsKnown;
+ mFlags = b.mFlags;
}
/**
@@ -113,6 +118,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public Bundle(PersistableBundle b) {
super(b);
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -152,14 +158,37 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
return super.getClassLoader();
}
- /** @hide */
+ /** {@hide} */
public boolean setAllowFds(boolean allowFds) {
- boolean orig = mAllowFds;
- mAllowFds = allowFds;
+ final boolean orig = (mFlags & FLAG_ALLOW_FDS) != 0;
+ if (allowFds) {
+ mFlags |= FLAG_ALLOW_FDS;
+ } else {
+ mFlags &= ~FLAG_ALLOW_FDS;
+ }
return orig;
}
/**
+ * Mark if this Bundle is okay to "defuse." That is, it's okay for system
+ * processes to ignore any {@link BadParcelableException} encountered when
+ * unparceling it, leaving an empty bundle in its place.
+ * <p>
+ * This should <em>only</em> be set when the Bundle reaches its final
+ * destination, otherwise a system process may clobber contents that were
+ * destined for an app that could have unparceled them.
+ *
+ * @hide
+ */
+ public void setDefusable(boolean defusable) {
+ if (defusable) {
+ mFlags |= FLAG_DEFUSABLE;
+ } else {
+ mFlags &= ~FLAG_DEFUSABLE;
+ }
+ }
+
+ /**
* Clones the current Bundle. The internal map is cloned, but the keys and
* values to which it refers are copied by reference.
*/
@@ -187,9 +216,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
@Override
public void clear() {
super.clear();
-
- mHasFds = false;
- mFdsKnown = true;
+ mFlags = FLAG_HAS_FDS_KNOWN;
}
/**
@@ -202,16 +229,20 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
bundle.unparcel();
mMap.putAll(bundle.mMap);
- // fd state is now known if and only if both bundles already knew
- mHasFds |= bundle.mHasFds;
- mFdsKnown = mFdsKnown && bundle.mFdsKnown;
+ // FD state is now known if and only if both bundles already knew
+ if ((bundle.mFlags & FLAG_HAS_FDS) != 0) {
+ mFlags |= FLAG_HAS_FDS;
+ }
+ if ((bundle.mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
+ }
}
/**
* Reports whether the bundle contains any parcelled file descriptors.
*/
public boolean hasFileDescriptors() {
- if (!mFdsKnown) {
+ if ((mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
boolean fdFound = false; // keep going until we find one or run out of data
if (mParcelledData != null) {
@@ -267,10 +298,12 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
}
}
- mHasFds = fdFound;
- mFdsKnown = true;
+ if (fdFound) {
+ mFlags |= FLAG_HAS_FDS;
+ }
+ mFlags |= FLAG_HAS_FDS_KNOWN;
}
- return mHasFds;
+ return (mFlags & FLAG_HAS_FDS) != 0;
}
/**
@@ -366,7 +399,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/**
@@ -404,7 +437,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
public void putParcelableArray(@Nullable String key, @Nullable Parcelable[] value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/**
@@ -419,14 +452,14 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
@Nullable ArrayList<? extends Parcelable> value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/** {@hide} */
public void putParcelableList(String key, List<? extends Parcelable> value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/**
@@ -441,7 +474,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
@Nullable SparseArray<? extends Parcelable> value) {
unparcel();
mMap.put(key, value);
- mFdsKnown = false;
+ mFlags &= ~FLAG_HAS_FDS_KNOWN;
}
/**
@@ -1094,7 +1127,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
@Override
public void writeToParcel(Parcel parcel, int flags) {
- final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
+ final boolean oldAllowFds = parcel.pushAllowFds((mFlags & FLAG_ALLOW_FDS) != 0);
try {
super.writeToParcelInner(parcel, flags);
} finally {
@@ -1109,8 +1142,10 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
public void readFromParcel(Parcel parcel) {
super.readFromParcelInner(parcel);
- mHasFds = mParcelledData.hasFileDescriptors();
- mFdsKnown = true;
+ mFlags = FLAG_HAS_FDS_KNOWN;
+ if (mParcelledData.hasFileDescriptors()) {
+ mFlags |= FLAG_HAS_FDS;
+ }
}
@Override
@@ -1125,5 +1160,4 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
}
return "Bundle[" + mMap.toString() + "]";
}
-
}