svn commit: r258316 - head/lib/libiconv_modules/UTF7

Tijl Coosemans tijl at FreeBSD.org
Mon Nov 18 18:14:24 UTC 2013


Author: tijl
Date: Mon Nov 18 18:14:23 2013
New Revision: 258316
URL: http://svnweb.freebsd.org/changeset/base/258316

Log:
  Bug fixes in iconv(3) UTF-7 support.
  
  - Add ' to the list of directly encoded characters and * to the list of
    optionally directly encoded characters as per RFC 2152.
  
  - In _citrus_UTF7_mbtoutf16 on end of input when the next output character
    has only been partially decoded, save a copy of the buffer of input
    characters (not just its length).  On the next call with more input
    characters this buffer is reprocessed together with the new input to
    form a fully decoded output character.
  
  - At the end of a base64 encoded sequence fully discard '-' (BASE64_OUT)
    by decrementing psenc->chlen and i.  This is needed to make room in
    psenc->ch (input buffer) in case the next input character starts a new
    base64 encoded sequence.  And also, if this is the end of input and no
    output character can be returned, this brings the encoder in the initial
    state as indicated by _citrus_UTF7_stdenc_get_state_desc_generic which
    is used by the caller to distinguish between no output and partial
    output.
  
  - In _citrus_UTF7_mbrtowc_priv pass the s parameter (input pointer)
    directly to _citrus_UTF7_mbtoutf16 instead of a copy (s0).  This way s
    is updated correctly in case of errors.
  
  - In _citrus_UTF7_mbrtowc_priv when called with psenc->surrogate set
    (previous call did not have enough input), retrieve the previously
    decoded UTF-16 character from (psenc->cache >> psenc->bits) instead of
    (psenc->cache >> 2).
  
  MFC after:	5 days

Modified:
  head/lib/libiconv_modules/UTF7/citrus_utf7.c

Modified: head/lib/libiconv_modules/UTF7/citrus_utf7.c
==============================================================================
--- head/lib/libiconv_modules/UTF7/citrus_utf7.c	Mon Nov 18 18:03:52 2013	(r258315)
+++ head/lib/libiconv_modules/UTF7/citrus_utf7.c	Mon Nov 18 18:14:23 2013	(r258316)
@@ -113,9 +113,9 @@ static const char base64[] =
 static const char direct[] =
 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 	"abcdefghijklmnopqrstuvwxyz"
-	"0123456789(),-./:?";
+	"0123456789'(),-./:?";
 
-static const char option[] = "!\"#$%&';<=>@[]^_`{|}";
+static const char option[] = "!\"#$%&*;<=>@[]^_`{|}";
 static const char spaces[] = " \t\r\n";
 
 #define	BASE64_BIT	6
@@ -165,6 +165,7 @@ _citrus_UTF7_mbtoutf16(_UTF7EncodingInfo
 				*nresult = (size_t)-2;
 				*s = s0;
 				sv.chlen = psenc->chlen;
+				memcpy(sv.ch, psenc->ch, sizeof(sv.ch));
 				*psenc = sv;
 				return (0);
 			}
@@ -202,6 +203,9 @@ _citrus_UTF7_mbtoutf16(_UTF7EncodingInfo
 						goto ilseq;
 					*u16 = (uint16_t)psenc->ch[i];
 					done = 1;
+				} else {
+					psenc->chlen--;
+					i--;
 				}
 			} else {
 				psenc->cache =
@@ -241,7 +245,6 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingI
     wchar_t * __restrict pwc, const char ** __restrict s, size_t n,
     _UTF7State * __restrict psenc, size_t * __restrict nresult)
 {
-	const char *s0;
 	uint32_t u32;
 	uint16_t hi, lo;
 	size_t nr, siz;
@@ -252,14 +255,13 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingI
 		*nresult = (size_t)_ENCODING_IS_STATE_DEPENDENT;
 		return (0);
 	}
-	s0 = *s;
 	if (psenc->surrogate) {
-		hi = (psenc->cache >> 2) & UTF16_MAX;
+		hi = (psenc->cache >> psenc->bits) & UTF16_MAX;
 		if (hi < HISRG_MIN || hi > HISRG_MAX)
 			return (EINVAL);
 		siz = 0;
 	} else {
-		err = _citrus_UTF7_mbtoutf16(ei, &hi, &s0, n, psenc, &nr);
+		err = _citrus_UTF7_mbtoutf16(ei, &hi, s, n, psenc, &nr);
 		if (nr == (size_t)-1 || nr == (size_t)-2) {
 			*nresult = nr;
 			return (err);
@@ -274,7 +276,7 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingI
 		}
 		psenc->surrogate = 1;
 	}
-	err = _citrus_UTF7_mbtoutf16(ei, &lo, &s0, n, psenc, &nr);
+	err = _citrus_UTF7_mbtoutf16(ei, &lo, s, n, psenc, &nr);
 	if (nr == (size_t)-1 || nr == (size_t)-2) {
 		*nresult = nr;
 		return (err);
@@ -286,7 +288,6 @@ _citrus_UTF7_mbrtowc_priv(_UTF7EncodingI
 	u32 = (hi << 10 | lo) + SRG_BASE;
 	siz += nr;
 done:
-	*s = s0;
 	if (pwc != NULL)
 		*pwc = (wchar_t)u32;
 	if (u32 == (uint32_t)0) {


More information about the svn-src-head mailing list