Bug 1553820 - Heap buffer overflow in icalparser.c parser_get_next_char. r=philipp
☠☠ backed out by f4628616dd10 ☠ ☠
authorluis.merino@x41-dsec.de
Tue, 04 Jun 2019 18:01:15 +0200
changeset 35764 383efc5887ecf146ecfb8f5e5853b5869242e27b
parent 35763 def9f7f3af210dc5ec4474802cded6c249ee4166
child 35765 f4628616dd10a3b267b6c2c9540b7492ab64f6fa
push id392
push userclokep@gmail.com
push dateMon, 02 Sep 2019 20:17:19 +0000
reviewersphilipp
bugs1553820
Bug 1553820 - Heap buffer overflow in icalparser.c parser_get_next_char. r=philipp Like https://github.com/libical/libical/blame/e84714e9d6ec724dca889531e11fb963cadc2dba/src/libical/icalparser.c#L147
calendar/libical/src/libical/icalparser.c
--- a/calendar/libical/src/libical/icalparser.c
+++ b/calendar/libical/src/libical/icalparser.c
@@ -185,35 +185,34 @@ icalvalue* icalvalue_new_From_string_wit
                                                 char* str, 
                                                 icalproperty **error);
 
 
 static
 char* parser_get_next_char(char c, char *str, int qm)
 {
     int quote_mode = 0;
-    char* p;
-
-    for(p=str; *p!=0; p++){
-	    if (qm == 1) {
-				if ( quote_mode == 0 && *p=='"' && *(p-1) != '\\' ){
-						quote_mode =1;
-						continue;
-				}
+    char *p = str;
+    char next_char = *p;
+    char prev_char = 0;
 
-				if ( quote_mode == 1 && *p=='"' && *(p-1) != '\\' ){
-						quote_mode =0;
-						continue;
-				}
-	    }
-		
-		if (quote_mode == 0 &&  *p== c  && *(p-1) != '\\' ){
-				return p;
-		} 
+    while (next_char != '\0') {
+        if ((prev_char != '\0') && (prev_char != '\\')) {
+            if (qm == 1 && next_char == '"') {
+                /* Encountered a quote, toggle quote mode */
+                quote_mode = !quote_mode;
+            } else if (quote_mode == 0 && next_char == c) {
+                /* Found a matching character out of quote mode, return it */
+                return p;
+            }
+        }
 
+        /* Save the previous character so we can check if it's a backslash in the next iteration */
+        prev_char = next_char;
+        next_char = *(++p);
     }
 
     return 0;
 }
 
 
 /** make a new tmp buffer out of a substring */
 static char* make_segment(char* start, char* end)