chiark / gitweb /
conf-parse: remove 4K line length limit
authorLennart Poettering <lennart@poettering.net>
Fri, 22 Sep 2017 16:26:35 +0000 (18:26 +0200)
committerSven Eden <yamakuzure@gmx.net>
Fri, 22 Sep 2017 16:26:35 +0000 (18:26 +0200)
Let's use read_line() to solve our long line limitation.

Fixes #3302.

src/shared/conf-parser.c

index ef295ea5795e171662db28f85befb28018c9461c..2005671fe4579bc8f865c309b399b82b12af5786 100644 (file)
 #include "alloc-util.h"
 #include "conf-files.h"
 #include "conf-parser.h"
+#include "def.h"
 #include "extract-word.h"
 #include "fd-util.h"
+#include "fileio.h"
 #include "fs-util.h"
 #include "log.h"
 #include "macro.h"
@@ -315,24 +317,44 @@ int config_parse(const char *unit,
         fd_warn_permissions(filename, fileno(f));
 
         for (;;) {
-                char buf[LINE_MAX], *l, *p, *c = NULL, *e;
+                _cleanup_free_ char *buf = NULL;
+                char *l, *p, *c = NULL, *e;
                 bool escaped = false;
 
-                if (!fgets(buf, sizeof buf, f)) {
-                        if (feof(f))
-                                break;
+                r = read_line(f, LONG_LINE_MAX, &buf);
+                if (r == 0)
+                        break;
+                if (r == -ENOBUFS) {
+                        if (warn)
+                                log_error_errno(r, "%s:%u: Line too long", filename, line);
+
+                        return r;
+                }
+                if (r < 0) {
+                        if (warn)
+                                log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line);
 
-                        return log_error_errno(errno, "Failed to read configuration file '%s': %m", filename);
+                        return r;
                 }
 
                 l = buf;
-                if (allow_bom && startswith(l, UTF8_BYTE_ORDER_MARK))
-                        l += strlen(UTF8_BYTE_ORDER_MARK);
-                allow_bom = false;
+                if (allow_bom) {
+                        char *q;
 
-                truncate_nl(l);
+                        q = startswith(buf, UTF8_BYTE_ORDER_MARK);
+                        if (q) {
+                                l = q;
+                                allow_bom = false;
+                        }
+                }
 
                 if (continuation) {
+                        if (strlen(continuation) + strlen(l) > LONG_LINE_MAX) {
+                                if (warn)
+                                        log_error("%s:%u: Continuation line too long", filename, line);
+                                return -ENOBUFS;
+                        }
+
                         c = strappend(continuation, l);
                         if (!c) {
                                 if (warn)
@@ -386,8 +408,7 @@ int config_parse(const char *unit,
 
                 if (r < 0) {
                         if (warn)
-                                log_warning_errno(r, "Failed to parse file '%s': %m",
-                                                  filename);
+                                log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
                         return r;
                 }
         }