From fc813796d239ca25871042bf32d5dbfdaa0c5ae0 Mon Sep 17 00:00:00 2001 From: "Tim J. Robbins" Date: Mon, 12 Apr 2004 13:09:18 +0000 Subject: [PATCH] Perform some basic validation of multibyte conversion state objects. --- lib/libc/locale/big5.c | 17 +++++++++++++++-- lib/libc/locale/euc.c | 16 ++++++++++++++-- lib/libc/locale/gb18030.c | 16 ++++++++++++++-- lib/libc/locale/gb2312.c | 17 +++++++++++++++-- lib/libc/locale/gbk.c | 17 +++++++++++++++-- lib/libc/locale/mskanji.c | 17 +++++++++++++++-- lib/libc/locale/utf2.c | 16 ++++++++++++++-- lib/libc/locale/utf8.c | 16 ++++++++++++++-- 8 files changed, 116 insertions(+), 16 deletions(-) diff --git a/lib/libc/locale/big5.c b/lib/libc/locale/big5.c index 0dbf04dda5b..d9adfba506d 100644 --- a/lib/libc/locale/big5.c +++ b/lib/libc/locale/big5.c @@ -41,6 +41,7 @@ static char sccsid[] = "@(#)big5.c 8.1 (Berkeley) 6/4/93"; #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -100,6 +101,11 @@ _BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, bs = (_BIG5State *)ps; + if (bs->count < 0 || bs->count > sizeof(bs->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) { s = ""; n = 1; @@ -127,9 +133,16 @@ _BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } size_t -_BIG5_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused) +_BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { + _BIG5State *bs; + + bs = (_BIG5State *)ps; + + if (bs->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } if (s == NULL) /* Reset to initial shift state (no-op) */ diff --git a/lib/libc/locale/euc.c b/lib/libc/locale/euc.c index 92a3d4c27ee..6a75033c553 100644 --- a/lib/libc/locale/euc.c +++ b/lib/libc/locale/euc.c @@ -154,6 +154,11 @@ _EUC_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, es = (_EucState *)ps; + if (es->count < 0 || es->count > sizeof(es->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) { s = ""; n = 1; @@ -192,12 +197,19 @@ _EUC_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } size_t -_EUC_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused) +_EUC_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { + _EucState *es; wchar_t m, nm; int i, len; + es = (_EucState *)ps; + + if (es->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); diff --git a/lib/libc/locale/gb18030.c b/lib/libc/locale/gb18030.c index ee895d5a1f0..30d9e471487 100644 --- a/lib/libc/locale/gb18030.c +++ b/lib/libc/locale/gb18030.c @@ -85,6 +85,11 @@ _GB18030_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, gs = (_GB18030State *)ps; + if (gs->count < 0 || gs->count > sizeof(gs->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) { s = ""; n = 1; @@ -154,12 +159,19 @@ ilseq: } size_t -_GB18030_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused) +_GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { + _GB18030State *gs; size_t len; int c; + gs = (_GB18030State *)ps; + + if (gs->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); diff --git a/lib/libc/locale/gb2312.c b/lib/libc/locale/gb2312.c index 70725d9cdcb..36f6e095b57 100644 --- a/lib/libc/locale/gb2312.c +++ b/lib/libc/locale/gb2312.c @@ -28,6 +28,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -102,6 +103,11 @@ _GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, gs = (_GB2312State *)ps; + if (gs->count < 0 || gs->count > sizeof(gs->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) { s = ""; n = 1; @@ -128,9 +134,16 @@ _GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } size_t -_GB2312_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused) +_GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { + _GB2312State *gs; + + gs = (_GB2312State *)ps; + + if (gs->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } if (s == NULL) /* Reset to initial shift state (no-op) */ diff --git a/lib/libc/locale/gbk.c b/lib/libc/locale/gbk.c index 09b3aecbc2e..fc42c55007e 100644 --- a/lib/libc/locale/gbk.c +++ b/lib/libc/locale/gbk.c @@ -38,6 +38,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -97,6 +98,11 @@ _GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, gs = (_GBKState *)ps; + if (gs->count < 0 || gs->count > sizeof(gs->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) { s = ""; n = 1; @@ -124,9 +130,16 @@ _GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } size_t -_GBK_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused) +_GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { + _GBKState *gs; + + gs = (_GBKState *)ps; + + if (gs->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } if (s == NULL) /* Reset to initial shift state (no-op) */ diff --git a/lib/libc/locale/mskanji.c b/lib/libc/locale/mskanji.c index 265ebe14f44..3f11b7c360f 100644 --- a/lib/libc/locale/mskanji.c +++ b/lib/libc/locale/mskanji.c @@ -39,6 +39,7 @@ static char sccsid[] = "@(#)mskanji.c 1.0 (Phase One) 5/5/95"; #include __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -90,6 +91,11 @@ _MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, ms = (_MSKanjiState *)ps; + if (ms->count < 0 || ms->count > sizeof(ms->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) { s = ""; n = 1; @@ -122,11 +128,18 @@ _MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } size_t -_MSKanji_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused) +_MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { + _MSKanjiState *ms; int len, i; + ms = (_MSKanjiState *)ps; + + if (ms->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) /* Reset to initial shift state (no-op) */ return (1); diff --git a/lib/libc/locale/utf2.c b/lib/libc/locale/utf2.c index 85e79d69a69..393a8082600 100644 --- a/lib/libc/locale/utf2.c +++ b/lib/libc/locale/utf2.c @@ -91,6 +91,11 @@ _UTF2_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, us = (_UTF2State *)ps; + if (us->count < 0 || us->count > sizeof(us->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) { s = ""; n = 1; @@ -142,12 +147,19 @@ _UTF2_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } size_t -_UTF2_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused) +_UTF2_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { + _UTF2State *us; unsigned char lead; int i, len; + us = (_UTF2State *)ps; + + if (us->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) /* Reset to initial conversion state. */ return (1); diff --git a/lib/libc/locale/utf8.c b/lib/libc/locale/utf8.c index 2bb6bb252c3..7585f5093f4 100644 --- a/lib/libc/locale/utf8.c +++ b/lib/libc/locale/utf8.c @@ -79,6 +79,11 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, us = (_UTF8State *)ps; + if (us->count < 0 || us->count > sizeof(us->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) { s = ""; n = 1; @@ -176,12 +181,19 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } size_t -_UTF8_wcrtomb(char * __restrict s, wchar_t wc, - mbstate_t * __restrict ps __unused) +_UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) { + _UTF8State *us; unsigned char lead; int i, len; + us = (_UTF8State *)ps; + + if (us->count < 0 || us->count > sizeof(us->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + if (s == NULL) /* Reset to initial shift state (no-op) */ return (1);