Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/dist/nvi/common It is ridiculous to truncate files on charac...



details:   https://anonhg.NetBSD.org/src/rev/131c4029a65b
branches:  trunk
changeset: 784269:131c4029a65b
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Jan 23 18:51:51 2013 +0000

description:
It is ridiculous to truncate files on character conversions without
warning and a chance for recovery. This patch sets the handler to
copy the character, clear the error and proceed instead of bailing
out.

To replicate:
        - unset LANG
        - Create a file that has ~1000 lines. Put a single bad character
        - '\344' in it, around 2/3rds of the file down. Save it.
        - export LANG=en_US.UTF-8
        - edit the file. Notice there is no error for input conversion,
          since nvi reads the file opportunistically.
        - :w Boom, the file is truncated.

Alternatively, you can put that character in the first line of the file,
and watch the fireworks. If you like to restore the previous behavior
compile with -DERROR_ON_CONVERT

XXX: Pullup to 6, 5 etc.

diffstat:

 dist/nvi/common/conv.c |  33 +++++++++++++++++++++++++--------
 1 files changed, 25 insertions(+), 8 deletions(-)

diffs (75 lines):

diff -r 514aace676f9 -r 131c4029a65b dist/nvi/common/conv.c
--- a/dist/nvi/common/conv.c    Wed Jan 23 18:04:33 2013 +0000
+++ b/dist/nvi/common/conv.c    Wed Jan 23 18:51:51 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: conv.c,v 1.6 2009/01/18 03:45:50 lukem Exp $ */
+/*     $NetBSD: conv.c,v 1.7 2013/01/23 18:51:51 christos Exp $ */
 
 /*-
  * Copyright (c) 1993, 1994
@@ -62,6 +62,21 @@
     return 0;
 }
 
+#ifndef ERROR_ON_CONVERT
+#define HANDLE_ICONV_ERROR(o, i, ol, il) do {                          \
+               *o++ = *i++;                                            \
+               ol--; il--;                                             \
+       } while (/*CONSTCOND*/0)
+#define HANDLE_MBR_ERROR(n, mbs, d, s) do {                            \
+               d = s;                                                  \
+               MEMSET(&mbs, 0, 1);                                     \
+               n = 1;                                                  \
+       } while (/*CONSTCOND*/0)
+#else
+#define HANDLE_ICONV_ERROR goto err
+#define        HANDLE_MBR_ERROR goto err
+#endif
+
 #define CONV_BUFFER_SIZE    512
 /* fill the buffer with codeset encoding of string pointed to by str
  * left has the number of bytes left in str and is adjusted
@@ -74,9 +89,9 @@
        char *bp = buffer;                                              \
        outleft = CONV_BUFFER_SIZE;                                     \
        errno = 0;                                                      \
-       if (iconv(id, (const char **)&str, &left, &bp, &outleft) == (size_t)-1 \
-               /* && errno != E2BIG */)                                \
-           goto err;                                                   \
+       if (iconv(id, (const char **)&str, &left, &bp, &outleft)        \
+           == (size_t)-1 /* && errno != E2BIG */)                      \
+               HANDLE_ICONV_ERROR(bp, str, outleft, left);             \
        if ((len = CONV_BUFFER_SIZE - outleft) == 0) {                  \
            error = -left;                                              \
            goto err;                                                   \
@@ -120,7 +135,8 @@
        n = mbrtowc((*tostr)+i, src+j, len-j, &mbs);
        /* NULL character converted */
        if (n == (size_t)-2) error = -(len-j);
-       if (n == (size_t)-1 || n == (size_t)-2) goto err;
+       if (n == (size_t)-1 || n == (size_t)-2)
+           HANDLE_MBR_ERROR(n, mbs, (*tostr)[i], src[j]); 
        if (n == 0) n = 1;
        j += n;
        if (++i >= *blen) {
@@ -243,8 +259,8 @@
            }                                                           \
            errno = 0;                                                  \
            if (iconv(id, &bp, &len, &obp, &outleft) == (size_t)-1 &&   \
-                   errno != E2BIG)                                     \
-               goto err;                                               \
+               errno != E2BIG)                                         \
+                   HANDLE_ICONV_ERROR(obp, bp, outleft, len);          \
            offset = cw->blen1 - outleft;                               \
        }                                                               \
     } while (0)
@@ -268,7 +284,8 @@
 
     for (i = 0, j = 0; i < (size_t)len; ++i) {
        n = wcrtomb(dst+j, str[i], &mbs);
-       if (n == (size_t)-1) goto err;
+       if (n == (size_t)-1) 
+          HANDLE_MBR_ERROR(n, mbs, dst[j], str[i]);
        j += n;
        if (buflen < j + MB_CUR_MAX) {
            if (id != (iconv_t)-1) {



Home | Main Index | Thread Index | Old Index