Fixed use of limited length buffer in ABC blif parser
authorClifford Wolf <clifford@clifford.at>
Tue, 31 Dec 2013 20:58:35 +0000 (21:58 +0100)
committerClifford Wolf <clifford@clifford.at>
Tue, 31 Dec 2013 20:58:35 +0000 (21:58 +0100)
passes/abc/blifparse.cc

index a630405c63fd4b1523e486b62071174d6ac69284..2d46d1a8ef6525f22fa8ddfa4081353b12fe03c4 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
-static bool read_next_line(char *buffer, int &line_count, FILE *f)
+static bool read_next_line(char *&buffer, size_t &buffer_size, int &line_count, FILE *f)
 {
+       int buffer_len = 0;
        buffer[0] = 0;
 
        while (1)
        {
-               int buffer_len = strlen(buffer);
+               buffer_len += strlen(buffer + buffer_len);
                while (buffer_len > 0 && (buffer[buffer_len-1] == ' ' || buffer[buffer_len-1] == '\t' ||
                                buffer[buffer_len-1] == '\r' || buffer[buffer_len-1] == '\n'))
                        buffer[--buffer_len] = 0;
 
+               if (buffer_size-buffer_len < 4096) {
+                       buffer_size *= 2;
+                       buffer = (char*)realloc(buffer, buffer_size);
+               }
+
                if (buffer_len == 0 || buffer[buffer_len-1] == '\\') {
                        if (buffer[buffer_len-1] == '\\')
                                buffer[--buffer_len] = 0;
                        line_count++;
-                       if (fgets(buffer+buffer_len, 4096-buffer_len, f) == NULL)
+                       if (fgets(buffer+buffer_len, buffer_size-buffer_len, f) == NULL)
                                return false;
                } else
                        return true;
@@ -56,12 +62,13 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name)
        module->name = "\\netlist";
        design->modules[module->name] = module;
 
-       char buffer[4096];
+       size_t buffer_size = 4096;
+       char *buffer = (char*)malloc(buffer_size);
        int line_count = 0;
 
        while (1)
        {
-               if (!read_next_line(buffer, line_count, f))
+               if (!read_next_line(buffer, buffer_size, line_count, f))
                        goto error;
 
        continue_without_read:
@@ -83,8 +90,10 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name)
                        if (!strcmp(cmd, ".model"))
                                continue;
 
-                       if (!strcmp(cmd, ".end"))
+                       if (!strcmp(cmd, ".end")) {
+                               free(buffer);
                                return design;
+                       }
 
                        if (!strcmp(cmd, ".inputs") || !strcmp(cmd, ".outputs")) {
                                char *p;
@@ -174,7 +183,7 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name)
                                if (input_sig.width == 0) {
                                        RTLIL::State state = RTLIL::State::Sa;
                                        while (1) {
-                                               if (!read_next_line(buffer, line_count, f))
+                                               if (!read_next_line(buffer, buffer_size, line_count, f))
                                                        goto error;
                                                for (int i = 0; buffer[i]; i++) {
                                                        if (buffer[i] == ' ' || buffer[i] == '\t')