зеркало из https://github.com/mozilla/pjs.git
Bug 315974: JSprintf functions cannot print jschar characters and strings
This commit is contained in:
Родитель
4f5f3e33cb
Коммит
bbc897b35a
|
@ -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--;
|
||||
|
|
Загрузка…
Ссылка в новой задаче