[PATCH 2/4] regedit: Parse file header for validation

Hugh McMaster hugh.mcmaster at outlook.com
Thu Mar 16 07:05:10 CDT 2017


Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
 programs/regedit/regproc.c | 81 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 57 insertions(+), 24 deletions(-)

diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c
index f88d863..ac64e27 100644
--- a/programs/regedit/regproc.c
+++ b/programs/regedit/regproc.c
@@ -646,11 +646,34 @@ static void processRegEntry31(WCHAR *line)
     closeKey();
 }
 
-/* version constants */
+enum reg_versions {
+    REG_VERSION_31,
+    REG_VERSION_40,
+    REG_VERSION_50,
+    REG_VERSION_INVALID
+};
+
+static enum reg_versions parse_file_header(WCHAR *s)
+{
+    static const WCHAR header_31[] = {'R','E','G','E','D','I','T',0};
+    static const WCHAR header_40[] = {'R','E','G','E','D','I','T','4',0};
+    static const WCHAR header_50[] = {'W','i','n','d','o','w','s',' ',
+                                      'R','e','g','i','s','t','r','y',' ','E','d','i','t','o','r',' ',
+                                      'V','e','r','s','i','o','n',' ','5','.','0','0',0};
+
+    while (*s && (*s == ' ' || *s == '\t')) s++;
+
+    if (!strcmpW(s, header_31))
+        return REG_VERSION_31;
 
-#define REG_VERSION_31  3
-#define REG_VERSION_40  4
-#define REG_VERSION_50  5
+    if (!strcmpW(s, header_40))
+        return REG_VERSION_40;
+
+    if (!strcmpW(s, header_50))
+        return REG_VERSION_50;
+
+    return REG_VERSION_INVALID;
+}
 
 /******************************************************************************
  * Processes a registry file.
@@ -669,10 +692,7 @@ static void processRegLinesA(FILE *in, char* first_chars)
     char *line; /* The start of the current line */
     WCHAR *lineW;
     unsigned long version = 0;
-
-    static const char header_31[] = "REGEDIT";
-    static const char header_40[] = "REGEDIT4";
-    static const char header_50[] = "Windows Registry Editor Version 5.00";
+    BOOL first_line = TRUE;
 
     buf = HeapAlloc(GetProcessHeap(), 0, line_size);
     CHECK_ENOUGH_MEMORY(buf);
@@ -769,22 +789,26 @@ static void processRegLinesA(FILE *in, char* first_chars)
                 *s_eol++ = '\0';
             *s_eol = '\0';
 
-	    /* Check if the line is a header string */
-	    if (!strcmp(line, header_31)) {
-		version = REG_VERSION_31;
-	    } else if (!strcmp(line, header_40)) {
-		version = REG_VERSION_40;
-	    } else if (!strcmp(line, header_50)) {
-		version = REG_VERSION_50;
-	    } else {
-		lineW = GetWideString(line);
-		if (version == REG_VERSION_31) {
-		    processRegEntry31(lineW);
-		} else if(version == REG_VERSION_40 || version == REG_VERSION_50) {
-		    processRegEntry(lineW, FALSE);
-		}
-		HeapFree(GetProcessHeap(), 0, lineW);
-	    }
+            lineW = GetWideString(line);
+
+            if (first_line)
+            {
+                version = parse_file_header(lineW);
+                if (version == REG_VERSION_INVALID)
+                {
+                    HeapFree(GetProcessHeap(), 0, lineW);
+                    HeapFree(GetProcessHeap(), 0, buf);
+                    return;
+                }
+                first_line = FALSE;
+            }
+
+            if (version == REG_VERSION_31)
+                processRegEntry31(lineW);
+            else
+                processRegEntry(lineW, FALSE);
+
+            HeapFree(GetProcessHeap(), 0, lineW);
             line = s_eol + 1;
         }
     }
@@ -860,6 +884,15 @@ static WCHAR *get_lineW(FILE *fp, WCHAR **buf)
 static void processRegLinesW(FILE *fp)
 {
     WCHAR *buf = NULL, *line;
+    int reg_version;
+
+    line = get_lineW(fp, &buf);
+    reg_version = parse_file_header(line);
+    if (reg_version == REG_VERSION_INVALID)
+    {
+        HeapFree(GetProcessHeap(), 0, buf);
+        return;
+    }
 
     while ((line = get_lineW(fp, &buf)))
         processRegEntry(line, TRUE);
-- 
2.7.4




More information about the wine-patches mailing list