Bug 315974: JSprintf functions cannot print jschar characters and strings

This commit is contained in:
daumling%adobe.com 2006-02-18 07:13:16 +00:00
Родитель 4f5f3e33cb
Коммит bbc897b35a
4 изменённых файлов: 79 добавлений и 12 удалений

Просмотреть файл

@ -448,14 +448,27 @@ QuoteString(Sprinter *sp, JSString *str, jschar quote)
break;
/* Use js_EscapeMap, \u, or \x only if necessary. */
if ((u = js_strchr(js_EscapeMap, c)) != NULL)
if ((u = js_strchr(js_EscapeMap, c)) != NULL) {
ok = Sprint(sp, "\\%c", (char)u[1]) >= 0;
else {
} else {
#ifdef JS_STRINGS_ARE_UTF8
/* print as UTF-8 string */
ok = Sprint(sp, "%hc", c) >= 0;
/* If this is a surrogate pair, make sure to print the pair. */
if (c >= 0xD800 && c <= 0xDBFF) {
jschar buffer[3];
buffer[0] = c;
buffer[1] = *++t;
buffer[2] = 0;
if (t == z) {
ok = JS_FALSE;
break;
}
ok = Sprint(sp, "%hs", buffer) >= 0;
} else {
/* Print as UTF-8 string. */
ok = Sprint(sp, "%hc", c) >= 0;
}
#else
/* Use \uxxxx or \xXX if the string cannot be displayed as UTF-8 */
/* Use \uXXXX or \xXX if the string cannot be displayed as UTF-8. */
ok = Sprint(sp, (c >> 8) ? "\\u%04X" : "\\x%02X", c) >= 0;
#endif
}

Просмотреть файл

@ -49,6 +49,8 @@
#include "jsprf.h"
#include "jslong.h"
#include "jsutil.h" /* Added by JSIFY */
#include "jspubtd.h"
#include "jsstr.h"
/*
** Note: on some platforms va_list is defined as an array,
@ -105,6 +107,7 @@ struct NumArgState{
#define TYPE_STRING 8
#define TYPE_DOUBLE 9
#define TYPE_INTSTR 10
#define TYPE_WSTRING 11
#define TYPE_UNKNOWN 20
#define FLAG_LEFT 0x1
@ -395,6 +398,27 @@ static int cvt_s(SprintfState *ss, const char *s, int width, int prec,
return fill2(ss, s ? s : "(null)", slen, width, flags);
}
static int cvt_ws(SprintfState *ss, const jschar *ws, int width, int prec,
int flags)
{
int result;
/*
* Supply NULL as the JSContext; errors are not reported,
* and malloc() is used to allocate the buffer buffer.
*/
if (ws) {
int slen = js_strlen(ws);
char *s = js_DeflateString(NULL, ws, slen);
if (!s)
return -1; /* JSStuffFunc error indicator. */
result = cvt_s(ss, s, width, prec, flags);
free(s);
} else {
result = cvt_s(ss, NULL, width, prec, flags);
}
return result;
}
/*
** BuildArgArray stands for Numbered Argument list Sprintf
** for example,
@ -578,7 +602,7 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv,
break;
case 's':
nas[ cn ].type = TYPE_STRING;
nas[ cn ].type = (nas[ cn ].type == TYPE_UINT16) ? TYPE_WSTRING : TYPE_STRING;
break;
case 'n':
@ -635,6 +659,8 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv,
case TYPE_STRING: (void)va_arg( ap, char* ); break;
case TYPE_WSTRING: (void)va_arg( ap, jschar* ); break;
case TYPE_INTSTR: (void)va_arg( ap, JSIntn* ); break;
case TYPE_DOUBLE: (void)va_arg( ap, double ); break;
@ -662,11 +688,13 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
int flags, width, prec, radix, type;
union {
char ch;
jschar wch;
int i;
long l;
JSInt64 ll;
double d;
const char *s;
const jschar* ws;
int *ip;
} u;
const char *fmt0;
@ -678,7 +706,10 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
struct NumArgState nasArray[ NAS_DEFAULT_NUM ];
char pattern[20];
const char *dolPt = NULL; /* in "%4$.2f", dolPt will poiont to . */
#ifdef JS_STRINGS_ARE_UTF8
char utf8buf[6];
int utf8len;
#endif
/*
** build an argument array, IF the fmt is numbered argument
@ -905,7 +936,6 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
break;
case 'c':
u.ch = va_arg(ap, int);
if ((flags & FLAG_LEFT) == 0) {
while (width-- > 1) {
rv = (*ss->stuff)(ss, " ", 1);
@ -914,7 +944,20 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
}
}
}
rv = (*ss->stuff)(ss, &u.ch, 1);
switch (type) {
case TYPE_INT16:
/* Treat %hc as %c if JS_STRINGS_ARE_UTF8 is undefined. */
#ifdef JS_STRINGS_ARE_UTF8
u.wch = va_arg(ap, int);
utf8len = js_OneUcs4ToUtf8Char (utf8buf, u.wch);
rv = (*ss->stuff)(ss, utf8buf, utf8len);
break;
#endif
case TYPE_INTN:
u.ch = va_arg(ap, int);
rv = (*ss->stuff)(ss, &u.ch, 1);
break;
}
if (rv < 0) {
return rv;
}
@ -953,8 +996,17 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
#endif
case 's':
u.s = va_arg(ap, const char*);
rv = cvt_s(ss, u.s, width, prec, flags);
if(type == TYPE_INT16) {
/*
* This would do a simple string/byte conversion
* if JS_STRINGS_ARE_UTF8 is not defined.
*/
u.ws = va_arg(ap, const jschar*);
rv = cvt_ws(ss, u.ws, width, prec, flags);
} else {
u.s = va_arg(ap, const char*);
rv = cvt_s(ss, u.s, width, prec, flags);
}
if (rv < 0) {
return rv;
}

Просмотреть файл

@ -50,7 +50,9 @@
** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above
** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above
** %s - string
** %hs - 16-bit version of above (only available if compiled with JS_STRINGS_ARE_UTF8)
** %c - character
** %hc - 16-bit version of above (only available if compiled with JS_STRINGS_ARE_UTF8)
** %p - pointer (deals with machine dependent pointer size)
** %f - float
** %g - float

Просмотреть файл

@ -2965,7 +2965,7 @@ js_DeflateStringToBuffer(JSContext *cx, const jschar *src, size_t srclen,
if (c < 0xD800 || c > 0xDBFF) {
v = c;
} else {
if (srclen < 2)
if (srclen < 1)
goto bufferTooSmall;
c2 = *src++;
srclen--;