Skip to content
Snippets Groups Projects
Commit 8a37450d authored by Alexandre Julliard's avatar Alexandre Julliard
Browse files

'used' should be set even if we are only computing the necessary

buffer size.
parent f25efa06
No related branches found
No related tags found
No related merge requests found
......@@ -76,33 +76,53 @@ static inline int is_valid_sbcs_mapping( const struct sbcs_table *table, int fla
}
/* query necessary dst length for src string */
static inline int get_length_sbcs( const struct sbcs_table *table, int flags,
const WCHAR *src, unsigned int srclen )
static int get_length_sbcs( const struct sbcs_table *table, int flags,
const WCHAR *src, unsigned int srclen, int *used )
{
unsigned int ret = srclen;
const unsigned char * const uni2cp_low = table->uni2cp_low;
const unsigned short * const uni2cp_high = table->uni2cp_high;
int ret, tmp;
WCHAR composed;
if (!used) used = &tmp; /* avoid checking on every char */
*used = 0;
if (flags & WC_COMPOSITECHECK)
for (ret = 0; srclen; ret++, src++, srclen--)
{
const unsigned char * const uni2cp_low = table->uni2cp_low;
const unsigned short * const uni2cp_high = table->uni2cp_high;
WCHAR composed;
WCHAR wch = *src;
unsigned char ch;
for (ret = 0; srclen > 1; ret++, srclen--, src++)
if ((flags & WC_COMPOSITECHECK) && (srclen > 1) && (composed = compose(src)))
{
if (!(composed = compose(src))) continue;
/* check if we should skip the next char */
/* in WC_DEFAULTCHAR and WC_DISCARDNS mode, we always skip */
/* the next char no matter if the composition is valid or not */
if (!(flags & (WC_DEFAULTCHAR|WC_DISCARDNS)))
/* now check if we can use the composed char */
ch = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)];
if (is_valid_sbcs_mapping( table, flags, composed, ch ))
{
/* we have a good mapping, use it */
src++;
srclen--;
continue;
}
/* no mapping for the composed char, check the other flags */
if (flags & WC_DEFAULTCHAR) /* use the default char instead */
{
*used = 1;
src++; /* skip the non-spacing char */
srclen--;
continue;
}
if (flags & WC_DISCARDNS) /* skip the second char of the composition */
{
unsigned char ch = uni2cp_low[uni2cp_high[composed >> 8] + (composed & 0xff)];
if (!is_valid_sbcs_mapping( table, flags, composed, ch )) continue;
src++;
srclen--;
}
src++;
srclen--;
/* WC_SEPCHARS is the default */
}
if (!*used)
{
ch = uni2cp_low[uni2cp_high[wch >> 8] + (wch & 0xff)];
*used = !is_valid_sbcs_mapping( table, flags, wch, ch );
}
if (srclen) ret++; /* last char */
}
return ret;
}
......@@ -238,15 +258,15 @@ static inline int is_valid_dbcs_mapping( const struct dbcs_table *table, int fla
/* query necessary dst length for src string */
static int get_length_dbcs( const struct dbcs_table *table, int flags,
const WCHAR *src, unsigned int srclen,
const char *defchar )
const char *defchar, int *used )
{
const unsigned short * const uni2cp_low = table->uni2cp_low;
const unsigned short * const uni2cp_high = table->uni2cp_high;
WCHAR defchar_value = table->info.def_char;
WCHAR composed;
int len;
int len, tmp;
if (!defchar && !(flags & WC_COMPOSITECHECK))
if (!defchar && !used && !(flags & WC_COMPOSITECHECK))
{
for (len = 0; srclen; srclen--, src++, len++)
{
......@@ -256,6 +276,8 @@ static int get_length_dbcs( const struct dbcs_table *table, int flags,
}
if (defchar) defchar_value = defchar[1] ? ((defchar[0] << 8) | defchar[1]) : defchar[0];
if (!used) used = &tmp; /* avoid checking on every char */
*used = 0;
for (len = 0; srclen; len++, srclen--, src++)
{
unsigned short res;
......@@ -278,6 +300,7 @@ static int get_length_dbcs( const struct dbcs_table *table, int flags,
if (flags & WC_DEFAULTCHAR) /* use the default char instead */
{
if (defchar_value & 0xff00) len++;
*used = 1;
src++; /* skip the non-spacing char */
srclen--;
continue;
......@@ -291,7 +314,11 @@ static int get_length_dbcs( const struct dbcs_table *table, int flags,
}
res = uni2cp_low[uni2cp_high[wch >> 8] + (wch & 0xff)];
if (!is_valid_dbcs_mapping( table, flags, wch, res )) res = defchar_value;
if (!is_valid_dbcs_mapping( table, flags, wch, res ))
{
res = defchar_value;
*used = 1;
}
if (res & 0xff00) len++;
}
return len;
......@@ -399,15 +426,18 @@ int cp_wcstombs( const union cptable *table, int flags,
{
if (table->info.char_size == 1)
{
if (!dstlen) return get_length_sbcs( &table->sbcs, flags, src, srclen );
if (flags || defchar || used)
{
if (!dstlen) return get_length_sbcs( &table->sbcs, flags, src, srclen, used );
return wcstombs_sbcs_slow( &table->sbcs, flags, src, srclen,
dst, dstlen, defchar, used );
}
if (!dstlen) return srclen;
return wcstombs_sbcs( &table->sbcs, src, srclen, dst, dstlen );
}
else /* mbcs */
{
if (!dstlen) return get_length_dbcs( &table->dbcs, flags, src, srclen, defchar );
if (!dstlen) return get_length_dbcs( &table->dbcs, flags, src, srclen, defchar, used );
if (flags || defchar || used)
return wcstombs_dbcs_slow( &table->dbcs, flags, src, srclen,
dst, dstlen, defchar, used );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment