From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yuri Lin <yurilin@google.com>
Date: Tue, 13 Sep 2022 12:53:19 -0400
Subject: [PATCH] Limit lengths of fields in Condition to a max length.

This app-generated input needs to not be too long to avoid errors in the process of writing to disk.

Bug: 242846316
Test: cts ConditionTest; atest ConditionTest; manually verified exploit apk is OK

Change-Id: Ic2fa8f06cc7a4c1f262115764fbd1be2a226b4b9
Merged-In: Ic2fa8f06cc7a4c1f262115764fbd1be2a226b4b9
(cherry picked from commit 81352c3775949c622441e10b468766441e35edc7)
(cherry picked from commit 5cb217fff3bc7184bd776a9dc2991e7fce5e25bd)
Merged-In: Ic2fa8f06cc7a4c1f262115764fbd1be2a226b4b9
---
 .../service/notification/Condition.java       | 38 +++++++++++++++++--
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
index 447afe62fd1a..5f65d401600a 100644
--- a/core/java/android/service/notification/Condition.java
+++ b/core/java/android/service/notification/Condition.java
@@ -94,6 +94,12 @@ public final class Condition implements Parcelable {
     @SystemApi
     public final int icon;
 
+    /**
+     * The maximum string length for any string contained in this condition.
+     * @hide
+     */
+    public static final int MAX_STRING_LENGTH = 1000;
+
     /**
      * An object representing the current state of a {@link android.app.AutomaticZenRule}.
      * @param id the {@link android.app.AutomaticZenRule#getConditionId()} of the zen rule
@@ -109,16 +115,19 @@ public final class Condition implements Parcelable {
         if (id == null) throw new IllegalArgumentException("id is required");
         if (summary == null) throw new IllegalArgumentException("summary is required");
         if (!isValidState(state)) throw new IllegalArgumentException("state is invalid: " + state);
-        this.id = id;
-        this.summary = summary;
-        this.line1 = line1;
-        this.line2 = line2;
+        this.id = getTrimmedUri(id);
+        this.summary = getTrimmedString(summary);
+        this.line1 = getTrimmedString(line1);
+        this.line2 = getTrimmedString(line2);
         this.icon = icon;
         this.state = state;
         this.flags = flags;
     }
 
     public Condition(Parcel source) {
+        // This constructor passes all fields directly into the constructor that takes all the
+        // fields as arguments; that constructor will trim each of the input strings to
+        // max length if necessary.
         this((Uri)source.readParcelable(Condition.class.getClassLoader()),
                 source.readString(),
                 source.readString(),
@@ -234,4 +243,25 @@ public final class Condition implements Parcelable {
             return new Condition[size];
         }
     };
+
+    /**
+     * Returns a truncated copy of the string if the string is longer than MAX_STRING_LENGTH.
+     */
+    private static String getTrimmedString(String input) {
+        if (input != null && input.length() > MAX_STRING_LENGTH) {
+            return input.substring(0, MAX_STRING_LENGTH);
+        }
+        return input;
+    }
+
+    /**
+     * Returns a truncated copy of the Uri by trimming the string representation to the maximum
+     * string length.
+     */
+    private static Uri getTrimmedUri(Uri input) {
+        if (input != null && input.toString().length() > MAX_STRING_LENGTH) {
+            return Uri.parse(getTrimmedString(input.toString()));
+        }
+        return input;
+    }
 }
