]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
Fixed comment parsing to not segfault on invalid header or on comment with embedded...
authorPatrice Fournier <pfournier@ifax.com>
Fri, 14 Sep 2007 16:30:08 +0000 (16:30 +0000)
committerPatrice Fournier <pfournier@ifax.com>
Fri, 14 Sep 2007 16:30:08 +0000 (16:30 +0000)
faxmail/MsgFmt.c++
faxmail/MsgFmt.h
faxmail/faxmail.c++

index 79f526abb7c06b9cb95fb1fa129bfcfd19315749..adc130b16d8e28ebafc802b50acb67b8f05dc90e 100644 (file)
@@ -83,6 +83,52 @@ MsgFmt::getLine(FILE* fd, fxStackBuffer& buf)
     return (true);
 }
 
+/*
+ * This function replaces comments with a single white space.
+ * Unclosed comments are automatically closed at end of string.
+ * Stray closing parentheses are left untouched, as are other invalid chars.
+ * Headers which can contain quoted strings should not go through this
+ * revision of this function as is doesn't honnor them and could end up doing
+ * the wrong thing.
+ */
+fxStr
+MsgFmt::stripComments(const fxStr& s)
+{
+    fxStr q;
+    u_int depth = 0;
+    bool wasSpace = true;
+    for (u_int i = 0; i < s.length(); i++) {
+        switch (s[i]) {
+            case '(':
+                depth++;
+                break;
+            case ')':
+                if (depth > 0)
+                    depth--;
+                break;
+            case '\\':
+                if (depth == 0) {
+                    q.append(s[i++]);     // Don't decode them at this time
+                    q.append(s[i]);
+                    wasSpace = false;
+                } else
+                  i++;
+                break;
+            default:
+                if (depth == 0) {
+                    if (!isspace(s[i]) || !wasSpace) {       // Trim consecutive spaces
+                        q.append(s[i]);
+                        wasSpace = isspace(s[i]);
+                    }
+                }
+                break;
+        }
+    }
+    while (q.length() > 0 && isspace(q[q.length()-1]))
+      q.remove(q.length()-1, 1);      // Trim trailing white space
+    return q;
+}
+
 void
 MsgFmt::parseHeaders(FILE* fd, u_int& lineno)
 {
@@ -99,17 +145,6 @@ MsgFmt::parseHeaders(FILE* fd, u_int& lineno)
         */ 
        fxStr line(&buf[0], buf.getLength());
        u_int len = line.length();
-       // trim any RFC 822 comment strings
-       u_int colon = line.next(0, ':');
-       if (colon < len) {
-           u_int paren = line.next(colon, '(');
-           while (paren < len) {
-               u_int csize = line.next(paren, ')') - paren + 1;
-               line.remove(paren, csize);
-               len -= csize;
-               paren = line.next(colon, '(');
-           }
-       }
        while (len > 0 && isspace(line[line.length()-1])) {
            line.remove(line.length()-1, 1);    // trim trailing whitespace
            len--;
index 6ff03cb9e4f9609ba13d1d423b875d820c2862ac..70d505df1a56f3ee611e37f6db4893d57221ca65 100644 (file)
@@ -51,6 +51,7 @@ struct MsgFmt {
     virtual bool setConfigItem(const char* tag, const char* value);
 
     static bool getLine(FILE* fd, fxStackBuffer& buf);
+    static fxStr stripComments(const fxStr& s);
 
     const fxStr* findHeader(const fxStr& name) const;
     u_int headerCount(void);
index a03b4c6a1286a50e71206d7c34cece7147597825..178d6de438e9ccdc168b406dc0a0e397e83ef2d8 100644 (file)
@@ -363,8 +363,11 @@ faxMailApp::run(int argc, char** argv)
     mimeid="part";
 
     const fxStr* version = findHeader("MIME-Version");
-    if (version && *version == "1.0") {
-        beginFile();
+
+    if (version && stripComments(*version) == "1.0") {
+       if (verbose)
+           fprintf(stderr, "faxmail: This is a MIME message\n");
+       beginFile();
        withinFile = true;
        // We only format top-level headers if they are
        // wanted
@@ -374,7 +377,9 @@ faxMailApp::run(int argc, char** argv)
         if (withinFile) endFile();
        withinFile = false;
     } else {
-        beginFile();
+       if (verbose)
+           fprintf(stderr, "faxmail: This is not a MIME message\n");
+       beginFile();
        withinFile = true;
        // We only format top-level headers if they are
        // wanted