Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libedit From Ingo Schwarze:
details: https://anonhg.NetBSD.org/src/rev/b478533402dd
branches: trunk
changeset: 813697:b478533402dd
user: christos <christos%NetBSD.org@localhost>
date: Sun Feb 14 17:06:24 2016 +0000
description:
>From Ingo Schwarze:
el_getc() for the WIDECHAR case, that is, the version in eln.c.
For a UTF-8 locale, it is broken in four ways:
1. If the character read is outside the ASCII range, the function
does an undefined cast from wchar_t to char. Even if wchar_t
is internally represented as UCS-4, that is wrong and dangerous
because characters beyond codepoint U+0255 get their high bits
truncated, meaning that perfectly valid printable Unicode
characters get mapped to arbitrary bytes, even the ASCII escape
character for some Unicode characters. But wchar_t need not
be implemented in terms of UCS-4, so the outcome of this function
is undefined for any and all input.
2. If insufficient space is available for the result, the function
fails to detect failure and returns garbage rather than -1 as
specified in the documentation.
3. The documentation says that errno will be set on failure, but
that doesn't happen either in the above case.
4. Even for ASCII characters, the results may be wrong if wchar_t
is not using UCS-4.
diffstat:
lib/libedit/chartype.h | 4 +++-
lib/libedit/eln.c | 21 +++++++++++++++------
2 files changed, 18 insertions(+), 7 deletions(-)
diffs (72 lines):
diff -r 3f1773b96c93 -r b478533402dd lib/libedit/chartype.h
--- a/lib/libedit/chartype.h Sun Feb 14 14:49:34 2016 +0000
+++ b/lib/libedit/chartype.h Sun Feb 14 17:06:24 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: chartype.h,v 1.19 2016/02/14 14:49:34 christos Exp $ */
+/* $NetBSD: chartype.h,v 1.20 2016/02/14 17:06:24 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -61,6 +61,7 @@
#endif
#define ct_mbrtowc mbrtowc
+#define ct_wctob wctob
#define ct_wctomb wctomb
#define ct_wctomb_reset wctomb(0,0)
#define ct_wcstombs wcstombs
@@ -113,6 +114,7 @@
#else /* NARROW */
size_t ct_mbrtowc(char *, const char *, size_t, void *);
+#define ct_wctob(w) ((int)(w))
#define ct_wctomb error
#define ct_wctomb_reset
#define ct_wcstombs(a, b, c) (strncpy(a, b, c), strlen(a))
diff -r 3f1773b96c93 -r b478533402dd lib/libedit/eln.c
--- a/lib/libedit/eln.c Sun Feb 14 14:49:34 2016 +0000
+++ b/lib/libedit/eln.c Sun Feb 14 17:06:24 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: eln.c,v 1.21 2016/02/12 17:23:21 christos Exp $ */
+/* $NetBSD: eln.c,v 1.22 2016/02/14 17:06:24 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -34,12 +34,13 @@
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: eln.c,v 1.21 2016/02/12 17:23:21 christos Exp $");
+__RCSID("$NetBSD: eln.c,v 1.22 2016/02/14 17:06:24 christos Exp $");
#endif /* not lint && not SCCSID */
#include "histedit.h"
#include "el.h"
#include "read.h"
+#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -50,10 +51,18 @@
int num_read;
wchar_t wc = 0;
- num_read = el_wgetc (el, &wc);
- if (num_read > 0)
- *cp = (char)wc;
- return num_read;
+ num_read = el_wgetc(el, &wc);
+ *cp = '\0';
+ if (num_read <= 0)
+ return num_read;
+ num_read = ct_wctob(wc);
+ if (num_read == EOF) {
+ errno = ERANGE;
+ return -1;
+ } else {
+ *cp = (char)num_read;
+ return 1;
+ }
}
Home |
Main Index |
Thread Index |
Old Index