Allow property values to have (escaped) trailing and leading whitespace. Bug 365345, r+sr=darin. Recheckin including fix for bug 378839, r=bsmedberg, sr=biesi
authorsmontagu@smontagu.org
Sun, 29 Apr 2007 10:51:38 -0700
changeset 915 ae8e14877745bf2cb3ce5a61e3163433a0696984
parent 914 5624b1041cf2eb8180475644b60a19d5a6fe9c0a
child 916 3a5b680f6d3646eef5c6de43f8d68aa4bedbb6b6
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, biesi
bugs365345, 378839
milestone1.9a5pre
Allow property values to have (escaped) trailing and leading whitespace. Bug 365345, r+sr=darin. Recheckin including fix for bug 378839, r=bsmedberg, sr=biesi
xpcom/ds/nsPersistentProperties.cpp
--- a/xpcom/ds/nsPersistentProperties.cpp
+++ b/xpcom/ds/nsPersistentProperties.cpp
@@ -171,91 +171,109 @@ nsPersistentProperties::Load(nsIInputStr
         c = Read();
       }
       if (c < 0) {
         break;
       }
       static const char trimThese[] = " \t";
       key.Trim(trimThese, PR_FALSE, PR_TRUE);
       c = Read();
-      nsAutoString value;
+      nsAutoString value, tempValue;
+      while ((c >= 0) && (c != '\r') && (c != '\n')) {
+        if (c == '\\') {
+          c = Read();
+          switch(c) {
+            case '\r':
+            case '\n':
+              // Only skip first EOL characters and then next line's
+              // whitespace characters. Skipping all EOL characters
+              // and all upcoming whitespace is too agressive.
+              if (c == '\r')
+                c = Read();
+              if (c == '\n')
+                c = Read();
+              while (c == ' ' || c == '\t')
+                c = Read();
+              continue;
+            default:
+              tempValue.Append((PRUnichar) '\\');
+              tempValue.Append((PRUnichar) c);
+          } // switch(c)
+        } else {
+          tempValue.Append((PRUnichar) c);
+        }
+        c = Read();
+      }
+      tempValue.Trim(trimThese, PR_TRUE, PR_TRUE);
+
       PRUint32 state  = 0;
       PRUnichar uchar = 0;
-      while ((c >= 0) && (c != '\r') && (c != '\n')) {
+      for (PRUint32 i = 0; i < tempValue.Length(); ++i) {
+        PRUnichar ch = tempValue[i];
         switch(state) {
           case 0:
-           if (c == '\\') {
-             c = Read();
-             switch(c) {
-               case '\r':
-               case '\n':
-                 // Only skip first EOL characters and then next line's
-                 // whitespace characters. Skipping all EOL characters
-                 // and all upcoming whitespace is too agressive.
-                 if (c == '\r')
-                    c = Read();
-                 if (c == '\n')
-                    c = Read();
-                 while (c == ' ' || c == '\t')
-                    c = Read();
-                 continue;
+           if (ch == '\\') {
+             ++i;
+             if (i == tempValue.Length())
+               break;
+             ch = tempValue[i];
+             switch(ch) {
                case 'u':
                case 'U':
                  state = 1;
                  uchar=0;
                  break;
                case 't':
                  value.Append(PRUnichar('\t'));
                  break;
                case 'n':
                  value.Append(PRUnichar('\n'));
                  break;
                case 'r':
                  value.Append(PRUnichar('\r'));
                  break;
                default:
-                 value.Append((PRUnichar) c);
-             } // switch(c)
+                 value.Append(ch);
+             } // switch(ch)
            } else {
-             value.Append((PRUnichar) c);
+             value.Append(ch);
            }
-           c = Read();
-           break;
+           continue;
          case 1:
          case 2:
          case 3:
          case 4:
-           if (('0' <= c) && (c <= '9')) {
-              uchar = (uchar << 4) | (c - '0');
+           if (('0' <= ch) && (ch <= '9')) {
+               uchar = (uchar << 4) | (ch - '0');
               state++;
-              c = Read();
-           } else if (('a' <= c) && (c <= 'f')) {
-              uchar = (uchar << 4) | (c - 'a' + 0x0a);
+              continue;
+           }
+           if (('a' <= ch) && (ch <= 'f')) {
+              uchar = (uchar << 4) | (ch - 'a' + 0x0a);
               state++;
-              c = Read();
-           } else if (('A' <= c) && (c <= 'F')) {
-              uchar = (uchar << 4) | (c - 'A' + 0x0a);
+              continue;
+           }
+           if (('A' <= ch) && (ch <= 'F')) {
+              uchar = (uchar << 4) | (ch - 'A' + 0x0a);
               state++;
-              c = Read();
-           } else {
-             value.Append((PRUnichar) uchar);
-             state = 0;
+              continue;
            }
-           break;
+           // if not hex digit, fall through
          case 5:
            value.Append((PRUnichar) uchar);
            state = 0;
+           --i;
+           break;
         }
       }
       if (state != 0) {
         value.Append((PRUnichar) uchar);
         state = 0;
       }
-
-      value.Trim(trimThese, PR_TRUE, PR_TRUE);
+      
       nsAutoString oldValue;
       mSubclass->SetStringProperty(NS_ConvertUTF16toUTF8(key), value, oldValue);
     }
   }
   mIn->Close();
   NS_RELEASE(mIn);
 
   return NS_OK;