]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
rev: use pointer-size-pairs instead of C-string
authorThomas Weißschuh <thomas@t-8ch.de>
Sat, 12 Nov 2022 04:09:38 +0000 (05:09 +0100)
committerThomas Weißschuh <thomas@t-8ch.de>
Sat, 12 Nov 2022 19:29:55 +0000 (20:29 +0100)
This allows us to properly handle zero-bytes

text-utils/rev.c

index 133d813931e276c2cf97992d6c873a90aafc33d7..568262f94f3ecc5aa561816a25342a8ffdcb0f9e 100644 (file)
@@ -96,6 +96,26 @@ static void reverse_str(wchar_t *str, size_t n)
        }
 }
 
+static size_t read_line(wchar_t *str, size_t n, FILE *stream)
+{
+       size_t r = 0;
+       while (r < n) {
+               wint_t c = fgetwc(stream);
+               if (c == WEOF)
+                       break;
+               str[r++] = c;
+               if (c == L'\n')
+                       break;
+       }
+       return r;
+}
+
+static void write_line(wchar_t *str, size_t n, FILE *stream)
+{
+       for (size_t i = 0; i < n; i++)
+               fputwc(str[i], stream);
+}
+
 int main(int argc, char *argv[])
 {
        char const *filename = "stdin";
@@ -146,14 +166,13 @@ int main(int argc, char *argv[])
                }
 
                line = 0;
-               while (fgetws(buf, bufsiz, fp)) {
-                       len = wcslen(buf);
-
+               while (!feof(fp)) {
+                       len = read_line(buf, bufsiz, fp);
                        if (len == 0)
                                continue;
 
                        /* This is my hack from setpwnam.c -janl */
-                       while (buf[len-1] != '\n' && !feof(fp)) {
+                       while (len == bufsiz && !feof(fp)) {
                                /* Extend input buffer if it failed getting the whole line */
                                /* So now we double the buffer size */
                                bufsiz *= 2;
@@ -161,15 +180,10 @@ int main(int argc, char *argv[])
                                buf = xrealloc(buf, bufsiz * sizeof(wchar_t));
 
                                /* And fill the rest of the buffer */
-                               if (!fgetws(&buf[len], bufsiz/2, fp))
-                                       break;
-
-                               len = wcslen(buf);
+                               len += read_line(&buf[len], bufsiz/2, fp);
                        }
-                       if (buf[len - 1] == '\n')
-                               buf[len--] = '\0';
-                       reverse_str(buf, len);
-                       fputws(buf, stdout);
+                       reverse_str(buf, buf[len - 1] == L'\n' ? len - 1 : len);
+                       write_line(buf, len, stdout);
                        line++;
                }
                if (ferror(fp)) {