Correctly account the number of bytes processed when outputting UTF-8 encoded
authormiod <miod@openbsd.org>
Mon, 6 Mar 2023 20:34:35 +0000 (20:34 +0000)
committermiod <miod@openbsd.org>
Mon, 6 Mar 2023 20:34:35 +0000 (20:34 +0000)
characters.

sys/dev/wscons/wsemul_sun.c
sys/dev/wscons/wsemul_vt100.c

index c866b11..40871af 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsemul_sun.c,v 1.35 2023/03/06 17:14:44 miod Exp $ */
+/* $OpenBSD: wsemul_sun.c,v 1.36 2023/03/06 20:34:35 miod Exp $ */
 /* $NetBSD: wsemul_sun.c,v 1.11 2000/01/05 11:19:36 drochner Exp $ */
 
 /*
@@ -662,7 +662,7 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel)
 {
        struct wsemul_sun_emuldata *edp = cookie;
        struct wsemul_inputstate *instate;
-       u_int processed = 0;
+       u_int prev_count, processed = 0;
 #ifdef HAVE_JUMP_SCROLL
        int lines;
 #endif
@@ -679,7 +679,7 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel)
        case ABORT_FAILED_CURSOR:
                /*
                 * If we could not display the cursor back, we pretended not
-                * having been able to display the last character. But this
+                * having been able to process the last byte. But this
                 * is a lie, so compensate here.
                 */
                data++, count--;
@@ -746,6 +746,7 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel)
 
                wsemul_resume_abort(&edp->abortstate);
 
+               prev_count = count;
                if (wsemul_getchar(&data, &count, instate,
 #ifdef HAVE_UTF8_SUPPORT
                    (edp->state == SUN_EMUL_STATE_NORMAL && !kernel) ?
@@ -760,7 +761,7 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel)
                        rc = wsemul_sun_output_lowchars(edp, instate, kernel);
                        if (rc != 0)
                                break;
-                       processed++;
+                       processed += prev_count - count;
                        continue;
                }
 
@@ -768,7 +769,7 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel)
                        rc = wsemul_sun_output_normal(edp, instate, 1);
                        if (rc != 0)
                                break;
-                       processed++;
+                       processed += prev_count - count;
                        continue;
                }
 
@@ -799,7 +800,7 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel)
                }
                if (rc != 0)
                        break;
-               processed++;
+               processed += prev_count - count;
        }
 
        if (rc != 0)
@@ -810,8 +811,9 @@ wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel)
                    (edp->emulcookie, 1, edp->crow, edp->ccol);
                if (rc != 0) {
                        /*
-                        * Fail the last character output, remembering that
-                        * only the cursor operation really needs to be done.
+                        * Pretend the last byte hasn't been processed, while
+                        * remembering that only the cursor operation really
+                        * needs to be done.
                         */
                        wsemul_abort_cursor(&edp->abortstate);
                        processed--;
index b58f223..1f976bd 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsemul_vt100.c,v 1.44 2023/03/06 17:14:44 miod Exp $ */
+/* $OpenBSD: wsemul_vt100.c,v 1.45 2023/03/06 20:34:35 miod Exp $ */
 /* $NetBSD: wsemul_vt100.c,v 1.13 2000/04/28 21:56:16 mycroft Exp $ */
 
 /*
@@ -1110,7 +1110,7 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel)
 {
        struct wsemul_vt100_emuldata *edp = cookie;
        struct wsemul_inputstate *instate;
-       u_int processed = 0;
+       u_int prev_count, processed = 0;
 #ifdef HAVE_JUMP_SCROLL
        int lines;
 #endif
@@ -1127,7 +1127,7 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel)
        case ABORT_FAILED_CURSOR:
                /*
                 * If we could not display the cursor back, we pretended not
-                * having been able to display the last character. But this
+                * having been able to process the last byte. But this
                 * is a lie, so compensate here.
                 */
                data++, count--;
@@ -1200,6 +1200,7 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel)
 
                wsemul_resume_abort(&edp->abortstate);
 
+               prev_count = count;
                if (wsemul_getchar(&data, &count, instate,
 #ifdef HAVE_UTF8_SUPPORT
                    (edp->state == VT100_EMUL_STATE_NORMAL && !kernel) ?
@@ -1215,7 +1216,7 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel)
                        rc = wsemul_vt100_output_c0c1(edp, instate, kernel);
                        if (rc != 0)
                                break;
-                       processed++;
+                       processed += prev_count - count;
                        continue;
                }
 
@@ -1223,7 +1224,7 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel)
                        rc = wsemul_vt100_output_normal(edp, instate, kernel);
                        if (rc != 0)
                                break;
-                       processed++;
+                       processed += prev_count - count;
                        continue;
                }
 #ifdef DIAGNOSTIC
@@ -1233,7 +1234,7 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel)
                rc = vt100_output[edp->state - 1](edp, instate);
                if (rc != 0)
                        break;
-               processed++;
+               processed += prev_count - count;
        }
 
        if (rc != 0)
@@ -1250,9 +1251,9 @@ wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel)
 #endif
                        if (rc != 0) {
                                /*
-                                * Fail the last character output, remembering
-                                * that only the cursor operation really needs
-                                * to be done.
+                                * Pretend the last byte hasn't been processed,
+                                * while remembering that only the cursor
+                                * operation really needs to be done.
                                 */
                                wsemul_abort_cursor(&edp->abortstate);
                                processed--;