ryantimwilson / rpms / systemd

Forked from rpms/systemd a month ago
Clone
923a60
From beef22775206d99b06c95c9a015e1b17bf3e767f Mon Sep 17 00:00:00 2001
923a60
From: Jan Synacek <jsynacek@redhat.com>
923a60
Date: Thu, 23 Nov 2017 10:13:52 +0100
923a60
Subject: [PATCH] conf-parse: remove 4K line length limit
923a60
923a60
Let's use read_line() to solve our long line limitation.
923a60
923a60
Fixes #3302.
923a60
(cherry picked from commit e6dde451a51dc5aaa7f4d98d39b8fe735f73d2af)
923a60
923a60
Resolves: #1503106
923a60
---
923a60
 src/shared/conf-parser.c | 50 +++++++++++++++++++++++++++++-----------
923a60
 src/shared/utf8.h        |  1 +
923a60
 2 files changed, 38 insertions(+), 13 deletions(-)
923a60
923a60
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
923a60
index 0b1af6c577..73e4d49ea1 100644
923a60
--- a/src/shared/conf-parser.c
923a60
+++ b/src/shared/conf-parser.c
923a60
@@ -28,6 +28,8 @@
923a60
 
923a60
 #include "conf-parser.h"
923a60
 #include "conf-files.h"
923a60
+#include "def.h"
923a60
+#include "fileio.h"
923a60
 #include "util.h"
923a60
 #include "macro.h"
923a60
 #include "strv.h"
923a60
@@ -339,7 +341,7 @@ int config_parse(const char *unit,
923a60
         _cleanup_free_ char *section = NULL, *continuation = NULL;
923a60
         _cleanup_fclose_ FILE *ours = NULL;
923a60
         unsigned line = 0, section_line = 0;
923a60
-        bool section_ignored = false;
923a60
+        bool section_ignored = false, allow_bom = true;
923a60
         int r;
923a60
 
923a60
         assert(filename);
923a60
@@ -359,21 +361,45 @@ int config_parse(const char *unit,
923a60
 
923a60
         fd_warn_permissions(filename, fileno(f));
923a60
 
923a60
-        while (!feof(f)) {
923a60
-                char l[LINE_MAX], *p, *c = NULL, *e;
923a60
+        for (;;) {
923a60
+                _cleanup_free_ char *buf = NULL;
923a60
+                char *l, *p, *c = NULL, *e;
923a60
                 bool escaped = false;
923a60
 
923a60
-                if (!fgets(l, sizeof(l), f)) {
923a60
-                        if (feof(f))
923a60
-                                break;
923a60
+                r = read_line(f, LONG_LINE_MAX, &buf;;
923a60
+                if (r == 0)
923a60
+                        break;
923a60
+                if (r == -ENOBUFS) {
923a60
+                        if (warn)
923a60
+                                log_error_errno(r, "%s:%u: Line too long", filename, line);
923a60
 
923a60
-                        log_error_errno(errno, "Failed to read configuration file '%s': %m", filename);
923a60
-                        return -errno;
923a60
+                        return r;
923a60
+                }
923a60
+                if (r < 0) {
923a60
+                        if (warn)
923a60
+                                log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line);
923a60
+
923a60
+                        return r;
923a60
                 }
923a60
 
923a60
-                truncate_nl(l);
923a60
+                l = buf;
923a60
+                if (allow_bom) {
923a60
+                        char *q;
923a60
+
923a60
+                        q = startswith(buf, UTF8_BYTE_ORDER_MARK);
923a60
+                        if (q) {
923a60
+                                l = q;
923a60
+                                allow_bom = false;
923a60
+                        }
923a60
+                }
923a60
 
923a60
                 if (continuation) {
923a60
+                        if (strlen(continuation) + strlen(l) > LONG_LINE_MAX) {
923a60
+                                if (warn)
923a60
+                                        log_error("%s:%u: Continuation line too long", filename, line);
923a60
+                                return -ENOBUFS;
923a60
+                        }
923a60
+
923a60
                         c = strappend(continuation, l);
923a60
                         if (!c) {
923a60
                                 if (warn)
923a60
@@ -381,8 +407,7 @@ int config_parse(const char *unit,
923a60
                                 return -ENOMEM;
923a60
                         }
923a60
 
923a60
-                        free(continuation);
923a60
-                        continuation = NULL;
923a60
+                        continuation = mfree(continuation);
923a60
                         p = c;
923a60
                 } else
923a60
                         p = l;
923a60
@@ -428,8 +453,7 @@ int config_parse(const char *unit,
923a60
 
923a60
                 if (r < 0) {
923a60
                         if (warn)
923a60
-                                log_warning_errno(r, "Failed to parse file '%s': %m",
923a60
-                                                  filename);
923a60
+                                log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
923a60
                         return r;
923a60
                 }
923a60
         }
923a60
diff --git a/src/shared/utf8.h b/src/shared/utf8.h
923a60
index 77f663438e..d31737061c 100644
923a60
--- a/src/shared/utf8.h
923a60
+++ b/src/shared/utf8.h
923a60
@@ -26,6 +26,7 @@
923a60
 #include "macro.h"
923a60
 
923a60
 #define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd"
923a60
+#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf"
923a60
 
923a60
 const char *utf8_is_valid(const char *s) _pure_;
923a60
 char *ascii_is_valid(const char *s) _pure_;