This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
one more tweak for the ISO-2022-CN-EXT converter
- To: libc-alpha at sources dot redhat dot com
- Subject: one more tweak for the ISO-2022-CN-EXT converter
- From: Bruno Haible <haible at ilog dot fr>
- Date: Thu, 21 Sep 2000 16:39:42 +0200 (CEST)
The ISO-2022-CN-EXT converter uses bits 2..17 for its internal state,
but bits 0..2 are sometimes cleared by the consume_incomplete feature
(iconv/loop.c:388 and iconv/skeleton.c:591). Currently this feature is
only enabled by mbrtowc, therefore no bug is visible, but it's still
dangerous because
- it's a bad example for other converters,
- the consume_incomplete feature might be used in other situations in
the future.
2000-09-21 Bruno Haible <haible@clisp.cons.org>
* iconvdata/iso-2022-cn-ext.c (EMIT_SHIFT_TO_INIT): Shift __count
by 3, not 2.
(INIT_PARAMS, UPDATE_PARAMS): Likewise.
*** glibc-20000914/iconvdata/iso-2022-cn-ext.c.bak Mon Sep 18 11:19:58 2000
--- glibc-20000914/iconvdata/iso-2022-cn-ext.c Thu Sep 21 13:28:52 2000
***************
*** 123,134 ****
the output state to the initial state. This has to be done during the
flushing. */
#define EMIT_SHIFT_TO_INIT \
! if (data->__statep->__count >> 2 != ASCII_set) \
{ \
if (FROM_DIRECTION) \
/* It's easy, we don't have to emit anything, we just reset the \
state for the input. */ \
! data->__statep->__count = ASCII_set << 2; \
else \
{ \
unsigned char *outbuf = data->__outbuf; \
--- 123,134 ----
the output state to the initial state. This has to be done during the
flushing. */
#define EMIT_SHIFT_TO_INIT \
! if (data->__statep->__count >> 3 != ASCII_set) \
{ \
if (FROM_DIRECTION) \
/* It's easy, we don't have to emit anything, we just reset the \
state for the input. */ \
! data->__statep->__count = ASCII_set << 3; \
else \
{ \
unsigned char *outbuf = data->__outbuf; \
***************
*** 145,151 ****
if (data->__flags & __GCONV_IS_LAST) \
*irreversible += 1; \
data->__outbuf = outbuf; \
! data->__statep->__count = ASCII_set << 2; \
} \
} \
}
--- 145,151 ----
if (data->__flags & __GCONV_IS_LAST) \
*irreversible += 1; \
data->__outbuf = outbuf; \
! data->__statep->__count = ASCII_set << 3; \
} \
} \
}
***************
*** 394,402 ****
*((uint32_t *) outptr)++ = ch; \
}
#define EXTRA_LOOP_DECLS , int *setp
! #define INIT_PARAMS int set = (*setp >> 2) & CURRENT_MASK; \
! int ann = (*setp >> 2) & ~CURRENT_MASK
! #define UPDATE_PARAMS *setp = (set | ann) << 2
#define LOOP_NEED_FLAGS
#include <iconv/loop.c>
--- 394,402 ----
*((uint32_t *) outptr)++ = ch; \
}
#define EXTRA_LOOP_DECLS , int *setp
! #define INIT_PARAMS int set = (*setp >> 3) & CURRENT_MASK; \
! int ann = (*setp >> 3) & ~CURRENT_MASK
! #define UPDATE_PARAMS *setp = (set | ann) << 3
#define LOOP_NEED_FLAGS
#include <iconv/loop.c>
***************
*** 644,652 ****
inptr += 4; \
}
#define EXTRA_LOOP_DECLS , int *setp
! #define INIT_PARAMS int set = (*setp >> 2) & CURRENT_MASK; \
! int ann = (*setp >> 2) & ~CURRENT_MASK
! #define UPDATE_PARAMS *setp = (set | ann) << 2
#define LOOP_NEED_FLAGS
#include <iconv/loop.c>
--- 644,652 ----
inptr += 4; \
}
#define EXTRA_LOOP_DECLS , int *setp
! #define INIT_PARAMS int set = (*setp >> 3) & CURRENT_MASK; \
! int ann = (*setp >> 3) & ~CURRENT_MASK
! #define UPDATE_PARAMS *setp = (set | ann) << 3
#define LOOP_NEED_FLAGS
#include <iconv/loop.c>