fileio: fix read_one_line() when reading bytes > 0x7F
authorLennart Poettering <lennart@poettering.net>
Thu, 20 Dec 2018 09:21:16 +0000 (10:21 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 20 Dec 2018 11:11:18 +0000 (12:11 +0100)
Fixes: #11218

src/basic/fileio.c
src/test/test-fileio.c

index 66e1273..e18b842 100644 (file)
@@ -755,9 +755,15 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) {
                             (eol == EOL_NONE && previous_eol != EOL_NONE) ||
                             (eol != EOL_NONE && (previous_eol & eol) != 0)) {
                                 /* Previous char was a NUL? This is not an EOL, but the previous char was? This type of
-                                 * EOL marker has been seen right before? In either of these three cases we are
-                                 * done. But first, let's put this character back in the queue. */
-                                assert_se(ungetc(c, f) != EOF);
+                                 * EOL marker has been seen right before?  In either of these three cases we are
+                                 * done. But first, let's put this character back in the queue. (Note that we have to
+                                 * cast this to (unsigned char) here as ungetc() expects a positive 'int', and if we
+                                 * are on an architecture where 'char' equals 'signed char' we need to ensure we don't
+                                 * pass a negative value here. That said, to complicate things further ungetc() is
+                                 * actually happy with most negative characters and implicitly casts them back to
+                                 * positive ones as needed, except for \xff (aka -1, aka EOF), which it refuses. What a
+                                 * godawful API!) */
+                                assert_se(ungetc((unsigned char) c, f) != EOF);
                                 break;
                         }
 
index f75b757..08ed66d 100644 (file)
@@ -778,7 +778,7 @@ static void test_read_line4(void) {
 static void test_read_nul_string(void) {
         static const char test[] = "string nr. 1\0"
                 "string nr. 2\n\0"
-                "empty string follows\0"
+                "\377empty string follows\0"
                 "\0"
                 "final string\n is empty\0"
                 "\0";
@@ -794,7 +794,7 @@ static void test_read_nul_string(void) {
         assert_se(read_nul_string(f, LONG_LINE_MAX, &s) == 14 && streq_ptr(s, "string nr. 2\n"));
         s = mfree(s);
 
-        assert_se(read_nul_string(f, LONG_LINE_MAX, &s) == 21 && streq_ptr(s, "empty string follows"));
+        assert_se(read_nul_string(f, LONG_LINE_MAX, &s) == 22 && streq_ptr(s, "\377empty string follows"));
         s = mfree(s);
 
         assert_se(read_nul_string(f, LONG_LINE_MAX, &s) == 1 && streq_ptr(s, ""));