mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 94593f55cd01 (bug 1251303) for ASAN failures
This commit is contained in:
parent
d76a08e7f9
commit
b44b7537c5
183
js/src/jsprf.cpp
183
js/src/jsprf.cpp
@ -39,13 +39,16 @@ using namespace js;
|
|||||||
#define VARARGS_ASSIGN(foo, bar) (foo) = (bar)
|
#define VARARGS_ASSIGN(foo, bar) (foo) = (bar)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct PrintBuffer
|
struct SprintfState
|
||||||
{
|
{
|
||||||
virtual bool append(const char* sp, size_t len) = 0;
|
bool (*stuff)(SprintfState* ss, const char* sp, size_t len);
|
||||||
|
|
||||||
char* base;
|
char* base;
|
||||||
char* cur;
|
char* cur;
|
||||||
size_t maxlen;
|
size_t maxlen;
|
||||||
|
|
||||||
|
int (*func)(void* arg, const char* sp, uint32_t len);
|
||||||
|
void* arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -81,13 +84,13 @@ typedef mozilla::Vector<NumArgState, 20, js::SystemAllocPolicy> NumArgStateVecto
|
|||||||
#define FLAG_NEG 0x10
|
#define FLAG_NEG 0x10
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
generic_write(PrintBuffer* buf, const char* src, size_t srclen)
|
generic_write(SprintfState* ss, const char* src, size_t srclen)
|
||||||
{
|
{
|
||||||
return buf->append(src, srclen);
|
return (*ss->stuff)(ss, src, srclen);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
generic_write(PrintBuffer* buf, const char16_t* src, size_t srclen)
|
generic_write(SprintfState* ss, const char16_t* src, size_t srclen)
|
||||||
{
|
{
|
||||||
const size_t CHUNK_SIZE = 64;
|
const size_t CHUNK_SIZE = 64;
|
||||||
char chunk[CHUNK_SIZE];
|
char chunk[CHUNK_SIZE];
|
||||||
@ -99,7 +102,7 @@ generic_write(PrintBuffer* buf, const char16_t* src, size_t srclen)
|
|||||||
chunk[j++] = char(src[i++]);
|
chunk[j++] = char(src[i++]);
|
||||||
|
|
||||||
if (j == CHUNK_SIZE || i == srclen) {
|
if (j == CHUNK_SIZE || i == srclen) {
|
||||||
if (!buf->append(chunk, j))
|
if (!(*ss->stuff)(ss, chunk, j))
|
||||||
return false;
|
return false;
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
@ -110,7 +113,7 @@ generic_write(PrintBuffer* buf, const char16_t* src, size_t srclen)
|
|||||||
// Fill into the buffer using the data in src
|
// Fill into the buffer using the data in src
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
static bool
|
static bool
|
||||||
fill2(PrintBuffer* buf, const Char* src, int srclen, int width, int flags)
|
fill2(SprintfState* ss, const Char* src, int srclen, int width, int flags)
|
||||||
{
|
{
|
||||||
char space = ' ';
|
char space = ' ';
|
||||||
|
|
||||||
@ -119,18 +122,18 @@ fill2(PrintBuffer* buf, const Char* src, int srclen, int width, int flags)
|
|||||||
if (flags & FLAG_ZEROS)
|
if (flags & FLAG_ZEROS)
|
||||||
space = '0';
|
space = '0';
|
||||||
while (--width >= 0) {
|
while (--width >= 0) {
|
||||||
if (!buf->append(&space, 1))
|
if (!(*ss->stuff)(ss, &space, 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy out the source data
|
// Copy out the source data
|
||||||
if (!generic_write(buf, src, srclen))
|
if (!generic_write(ss, src, srclen))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (width > 0 && (flags & FLAG_LEFT) != 0) { // Left adjusting
|
if (width > 0 && (flags & FLAG_LEFT) != 0) { // Left adjusting
|
||||||
while (--width >= 0) {
|
while (--width >= 0) {
|
||||||
if (!buf->append(&space, 1))
|
if (!(*ss->stuff)(ss, &space, 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,7 +144,7 @@ fill2(PrintBuffer* buf, const Char* src, int srclen, int width, int flags)
|
|||||||
* Fill a number. The order is: optional-sign zero-filling conversion-digits
|
* Fill a number. The order is: optional-sign zero-filling conversion-digits
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
fill_n(PrintBuffer* buf, const char* src, int srclen, int width, int prec, int type, int flags)
|
fill_n(SprintfState* ss, const char* src, int srclen, int width, int prec, int type, int flags)
|
||||||
{
|
{
|
||||||
int zerowidth = 0;
|
int zerowidth = 0;
|
||||||
int precwidth = 0;
|
int precwidth = 0;
|
||||||
@ -191,32 +194,32 @@ fill_n(PrintBuffer* buf, const char* src, int srclen, int width, int prec, int t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (--leftspaces >= 0) {
|
while (--leftspaces >= 0) {
|
||||||
if (!buf->append(" ", 1))
|
if (!(*ss->stuff)(ss, " ", 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (signwidth) {
|
if (signwidth) {
|
||||||
if (!buf->append(&sign, 1))
|
if (!(*ss->stuff)(ss, &sign, 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (--precwidth >= 0) {
|
while (--precwidth >= 0) {
|
||||||
if (!buf->append("0", 1))
|
if (!(*ss->stuff)(ss, "0", 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (--zerowidth >= 0) {
|
while (--zerowidth >= 0) {
|
||||||
if (!buf->append("0", 1))
|
if (!(*ss->stuff)(ss, "0", 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!buf->append(src, uint32_t(srclen)))
|
if (!(*ss->stuff)(ss, src, uint32_t(srclen)))
|
||||||
return false;
|
return false;
|
||||||
while (--rightspaces >= 0) {
|
while (--rightspaces >= 0) {
|
||||||
if (!buf->append(" ", 1))
|
if (!(*ss->stuff)(ss, " ", 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a long into its printable form. */
|
/* Convert a long into its printable form. */
|
||||||
static bool cvt_l(PrintBuffer* buf, long num, int width, int prec, int radix,
|
static bool cvt_l(SprintfState* ss, long num, int width, int prec, int radix,
|
||||||
int type, int flags, const char* hexp)
|
int type, int flags, const char* hexp)
|
||||||
{
|
{
|
||||||
char cvtbuf[100];
|
char cvtbuf[100];
|
||||||
@ -245,11 +248,11 @@ static bool cvt_l(PrintBuffer* buf, long num, int width, int prec, int radix,
|
|||||||
|
|
||||||
// Now that we have the number converted without its sign, deal with
|
// Now that we have the number converted without its sign, deal with
|
||||||
// the sign and zero padding.
|
// the sign and zero padding.
|
||||||
return fill_n(buf, cvt, digits, width, prec, type, flags);
|
return fill_n(ss, cvt, digits, width, prec, type, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a 64-bit integer into its printable form. */
|
/* Convert a 64-bit integer into its printable form. */
|
||||||
static bool cvt_ll(PrintBuffer* buf, int64_t num, int width, int prec, int radix,
|
static bool cvt_ll(SprintfState* ss, int64_t num, int width, int prec, int radix,
|
||||||
int type, int flags, const char* hexp)
|
int type, int flags, const char* hexp)
|
||||||
{
|
{
|
||||||
// According to the man page, this needs to happen.
|
// According to the man page, this needs to happen.
|
||||||
@ -278,14 +281,14 @@ static bool cvt_ll(PrintBuffer* buf, int64_t num, int width, int prec, int radix
|
|||||||
|
|
||||||
// Now that we have the number converted without its sign, deal with
|
// Now that we have the number converted without its sign, deal with
|
||||||
// the sign and zero padding.
|
// the sign and zero padding.
|
||||||
return fill_n(buf, cvt, digits, width, prec, type, flags);
|
return fill_n(ss, cvt, digits, width, prec, type, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert a double precision floating point number into its printable
|
* Convert a double precision floating point number into its printable
|
||||||
* form.
|
* form.
|
||||||
*/
|
*/
|
||||||
static bool cvt_f(PrintBuffer* buf, double d, const char* fmt0, const char* fmt1)
|
static bool cvt_f(SprintfState* ss, double d, const char* fmt0, const char* fmt1)
|
||||||
{
|
{
|
||||||
char fin[20];
|
char fin[20];
|
||||||
char fout[300];
|
char fout[300];
|
||||||
@ -311,7 +314,7 @@ static bool cvt_f(PrintBuffer* buf, double d, const char* fmt0, const char* fmt1
|
|||||||
#endif
|
#endif
|
||||||
snprintf_literal(fout, fin, d);
|
snprintf_literal(fout, fin, d);
|
||||||
|
|
||||||
return buf->append(fout, strlen(fout));
|
return (*ss->stuff)(ss, fout, strlen(fout));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char* generic_null_str(const char*) { return "(null)"; }
|
static inline const char* generic_null_str(const char*) { return "(null)"; }
|
||||||
@ -327,7 +330,7 @@ static inline size_t generic_strlen(const char16_t* s) { return js_strlen(s); }
|
|||||||
*/
|
*/
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
static bool
|
static bool
|
||||||
cvt_s(PrintBuffer* buf, const Char* s, int width, int prec, int flags)
|
cvt_s(SprintfState* ss, const Char* s, int width, int prec, int flags)
|
||||||
{
|
{
|
||||||
if (prec == 0)
|
if (prec == 0)
|
||||||
return true;
|
return true;
|
||||||
@ -340,7 +343,7 @@ cvt_s(PrintBuffer* buf, const Char* s, int width, int prec, int flags)
|
|||||||
slen = prec;
|
slen = prec;
|
||||||
|
|
||||||
// and away we go
|
// and away we go
|
||||||
return fill2(buf, s, slen, width, flags);
|
return fill2(ss, s, slen, width, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -567,7 +570,7 @@ BuildArgArray(const char* fmt, va_list ap, NumArgStateVector& nas)
|
|||||||
* The workhorse sprintf code.
|
* The workhorse sprintf code.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
dosprintf(SprintfState* ss, const char* fmt, va_list ap)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
int flags, width, prec, radix, type;
|
int flags, width, prec, radix, type;
|
||||||
@ -601,7 +604,7 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
|
|
||||||
while ((c = *fmt++) != 0) {
|
while ((c = *fmt++) != 0) {
|
||||||
if (c != '%') {
|
if (c != '%') {
|
||||||
if (!buf->append(fmt - 1, 1))
|
if (!(*ss->stuff)(ss, fmt - 1, 1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -614,7 +617,7 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
c = *fmt++;
|
c = *fmt++;
|
||||||
if (c == '%') {
|
if (c == '%') {
|
||||||
// quoting a % with %%
|
// quoting a % with %%
|
||||||
if (!buf->append(fmt - 1, 1))
|
if (!(*ss->stuff)(ss, fmt - 1, 1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -763,7 +766,7 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
case TYPE_UINT32:
|
case TYPE_UINT32:
|
||||||
u.l = (long)va_arg(ap, uint32_t);
|
u.l = (long)va_arg(ap, uint32_t);
|
||||||
do_long:
|
do_long:
|
||||||
if (!cvt_l(buf, u.l, width, prec, radix, type, flags, hexp))
|
if (!cvt_l(ss, u.l, width, prec, radix, type, flags, hexp))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -778,7 +781,7 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
case TYPE_UINT64:
|
case TYPE_UINT64:
|
||||||
u.ll = va_arg(ap, uint64_t);
|
u.ll = va_arg(ap, uint64_t);
|
||||||
do_longlong:
|
do_longlong:
|
||||||
if (!cvt_ll(buf, u.ll, width, prec, radix, type, flags, hexp))
|
if (!cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -795,11 +798,11 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
if (i < int(sizeof(pattern))) {
|
if (i < int(sizeof(pattern))) {
|
||||||
pattern[0] = '%';
|
pattern[0] = '%';
|
||||||
js_memcpy(&pattern[1], dolPt, size_t(i));
|
js_memcpy(&pattern[1], dolPt, size_t(i));
|
||||||
if (!cvt_f(buf, u.d, pattern, &pattern[i + 1]))
|
if (!cvt_f(ss, u.d, pattern, &pattern[i + 1]))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!cvt_f(buf, u.d, fmt0, fmt))
|
if (!cvt_f(ss, u.d, fmt0, fmt))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,7 +811,7 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
case 'c':
|
case 'c':
|
||||||
if ((flags & FLAG_LEFT) == 0) {
|
if ((flags & FLAG_LEFT) == 0) {
|
||||||
while (width-- > 1) {
|
while (width-- > 1) {
|
||||||
if (!buf->append(" ", 1))
|
if (!(*ss->stuff)(ss, " ", 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -816,13 +819,13 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
case TYPE_INT16:
|
case TYPE_INT16:
|
||||||
case TYPE_INTN:
|
case TYPE_INTN:
|
||||||
u.ch = va_arg(ap, int);
|
u.ch = va_arg(ap, int);
|
||||||
if (!buf->append(&u.ch, 1))
|
if (!(*ss->stuff)(ss, &u.ch, 1))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (flags & FLAG_LEFT) {
|
if (flags & FLAG_LEFT) {
|
||||||
while (width-- > 1) {
|
while (width-- > 1) {
|
||||||
if (!buf->append(" ", 1))
|
if (!(*ss->stuff)(ss, " ", 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -855,11 +858,11 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
case 's':
|
case 's':
|
||||||
if(type == TYPE_INT16) {
|
if(type == TYPE_INT16) {
|
||||||
u.ws = va_arg(ap, const char16_t*);
|
u.ws = va_arg(ap, const char16_t*);
|
||||||
if (!cvt_s(buf, u.ws, width, prec, flags))
|
if (!cvt_s(ss, u.ws, width, prec, flags))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
u.s = va_arg(ap, const char*);
|
u.s = va_arg(ap, const char*);
|
||||||
if (!cvt_s(buf, u.s, width, prec, flags))
|
if (!cvt_s(ss, u.s, width, prec, flags))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -867,7 +870,7 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
case 'n':
|
case 'n':
|
||||||
u.ip = va_arg(ap, int*);
|
u.ip = va_arg(ap, int*);
|
||||||
if (u.ip) {
|
if (u.ip) {
|
||||||
*u.ip = buf->cur - buf->base;
|
*u.ip = ss->cur - ss->base;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -876,15 +879,15 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
#if 0
|
#if 0
|
||||||
MOZ_ASSERT(0);
|
MOZ_ASSERT(0);
|
||||||
#endif
|
#endif
|
||||||
if (!buf->append("%", 1))
|
if (!(*ss->stuff)(ss, "%", 1))
|
||||||
return false;
|
return false;
|
||||||
if (!buf->append(fmt - 1, 1))
|
if (!(*ss->stuff)(ss, fmt - 1, 1))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stuff trailing NUL
|
// Stuff trailing NUL
|
||||||
if (!buf->append("\0", 1))
|
if (!(*ss->stuff)(ss, "\0", 1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -893,41 +896,36 @@ dosprintf(PrintBuffer* buf, const char* fmt, va_list ap)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print buffer that automatically grows the js_malloc'd output buffer
|
* Stuff routine that automatically grows the js_malloc'd output buffer
|
||||||
* before it overflows.
|
* before it overflows.
|
||||||
*/
|
*/
|
||||||
struct DynamicBuffer : public PrintBuffer
|
static bool
|
||||||
{
|
GrowStuff(SprintfState* ss, const char* sp, size_t len)
|
||||||
bool append(const char* sp, size_t len) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool
|
|
||||||
DynamicBuffer::append(const char* sp, size_t len)
|
|
||||||
{
|
{
|
||||||
ptrdiff_t off;
|
ptrdiff_t off;
|
||||||
char* newbase;
|
char* newbase;
|
||||||
size_t newlen;
|
size_t newlen;
|
||||||
|
|
||||||
off = cur - base;
|
off = ss->cur - ss->base;
|
||||||
if (off + len >= maxlen) {
|
if (off + len >= ss->maxlen) {
|
||||||
/* Grow the buffer */
|
/* Grow the buffer */
|
||||||
newlen = maxlen + ((len > 32) ? len : 32);
|
newlen = ss->maxlen + ((len > 32) ? len : 32);
|
||||||
newbase = static_cast<char*>(js_realloc(base, newlen));
|
newbase = static_cast<char*>(js_realloc(ss->base, newlen));
|
||||||
if (!newbase) {
|
if (!newbase) {
|
||||||
/* Ran out of memory */
|
/* Ran out of memory */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
base = newbase;
|
ss->base = newbase;
|
||||||
maxlen = newlen;
|
ss->maxlen = newlen;
|
||||||
cur = base + off;
|
ss->cur = ss->base + off;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy data */
|
/* Copy data */
|
||||||
while (len) {
|
while (len) {
|
||||||
--len;
|
--len;
|
||||||
*cur++ = *sp++;
|
*ss->cur++ = *sp++;
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(size_t(cur - base) <= maxlen);
|
MOZ_ASSERT(size_t(ss->cur - ss->base) <= ss->maxlen);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,36 +956,32 @@ JS_smprintf_free(char* mem)
|
|||||||
JS_PUBLIC_API(char*)
|
JS_PUBLIC_API(char*)
|
||||||
JS_vsmprintf(const char* fmt, va_list ap)
|
JS_vsmprintf(const char* fmt, va_list ap)
|
||||||
{
|
{
|
||||||
DynamicBuffer buf;
|
SprintfState ss;
|
||||||
|
|
||||||
buf.base = 0;
|
ss.stuff = GrowStuff;
|
||||||
buf.cur = 0;
|
ss.base = 0;
|
||||||
buf.maxlen = 0;
|
ss.cur = 0;
|
||||||
if (!dosprintf(&buf, fmt, ap)) {
|
ss.maxlen = 0;
|
||||||
js_free(buf.base);
|
if (!dosprintf(&ss, fmt, ap)) {
|
||||||
|
js_free(ss.base);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return buf.base;
|
return ss.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print buffer that discards overflow data
|
* Stuff routine that discards overflow data
|
||||||
*/
|
*/
|
||||||
struct FixedBuffer : public PrintBuffer
|
static bool
|
||||||
|
LimitStuff(SprintfState* ss, const char* sp, size_t len)
|
||||||
{
|
{
|
||||||
bool append(const char* sp, size_t len) override;
|
size_t limit = ss->maxlen - (ss->cur - ss->base);
|
||||||
};
|
|
||||||
|
|
||||||
bool
|
|
||||||
FixedBuffer::append(const char* sp, size_t len)
|
|
||||||
{
|
|
||||||
size_t limit = maxlen - (cur - base);
|
|
||||||
|
|
||||||
if (len > limit)
|
if (len > limit)
|
||||||
len = limit;
|
len = limit;
|
||||||
while (len) {
|
while (len) {
|
||||||
--len;
|
--len;
|
||||||
*cur++ = *sp++;
|
*ss->cur++ = *sp++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1015,24 +1009,24 @@ JS_snprintf(char* out, uint32_t outlen, const char* fmt, ...)
|
|||||||
JS_PUBLIC_API(uint32_t)
|
JS_PUBLIC_API(uint32_t)
|
||||||
JS_vsnprintf(char* out, uint32_t outlen, const char* fmt, va_list ap)
|
JS_vsnprintf(char* out, uint32_t outlen, const char* fmt, va_list ap)
|
||||||
{
|
{
|
||||||
FixedBuffer buf;
|
SprintfState ss;
|
||||||
|
|
||||||
if (outlen == 0)
|
if (outlen == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
buf.base = out;
|
ss.stuff = LimitStuff;
|
||||||
buf.cur = out;
|
ss.base = out;
|
||||||
buf.maxlen = outlen;
|
ss.cur = out;
|
||||||
|
ss.maxlen = outlen;
|
||||||
|
(void) dosprintf(&ss, fmt, ap);
|
||||||
|
|
||||||
(void) dosprintf(&buf, fmt, ap);
|
uint32_t charsWritten = ss.cur - ss.base;
|
||||||
|
|
||||||
uint32_t charsWritten = buf.cur - buf.base;
|
|
||||||
MOZ_RELEASE_ASSERT(charsWritten > 0);
|
MOZ_RELEASE_ASSERT(charsWritten > 0);
|
||||||
|
|
||||||
// If we didn't append a null then we must have hit the buffer limit. Write
|
// If we didn't append a null then we must have hit the buffer limit. Write
|
||||||
// a null terminator now and return a value indicating that we failed.
|
// a null terminator now and return a value indicating that we failed.
|
||||||
if (buf.cur[-1] != '\0') {
|
if (ss.cur[-1] != '\0') {
|
||||||
buf.cur[-1] = '\0';
|
ss.cur[-1] = '\0';
|
||||||
return outlen;
|
return outlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1056,23 +1050,24 @@ JS_sprintf_append(char* last, const char* fmt, ...)
|
|||||||
JS_PUBLIC_API(char*)
|
JS_PUBLIC_API(char*)
|
||||||
JS_vsprintf_append(char* last, const char* fmt, va_list ap)
|
JS_vsprintf_append(char* last, const char* fmt, va_list ap)
|
||||||
{
|
{
|
||||||
DynamicBuffer buf;
|
SprintfState ss;
|
||||||
|
|
||||||
|
ss.stuff = GrowStuff;
|
||||||
if (last) {
|
if (last) {
|
||||||
size_t lastlen = strlen(last);
|
size_t lastlen = strlen(last);
|
||||||
buf.base = last;
|
ss.base = last;
|
||||||
buf.cur = last + lastlen;
|
ss.cur = last + lastlen;
|
||||||
buf.maxlen = lastlen;
|
ss.maxlen = lastlen;
|
||||||
} else {
|
} else {
|
||||||
buf.base = 0;
|
ss.base = 0;
|
||||||
buf.cur = 0;
|
ss.cur = 0;
|
||||||
buf.maxlen = 0;
|
ss.maxlen = 0;
|
||||||
}
|
}
|
||||||
if (!dosprintf(&buf, fmt, ap)) {
|
if (!dosprintf(&ss, fmt, ap)) {
|
||||||
js_free(buf.base);
|
js_free(ss.base);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return buf.base;
|
return ss.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef TYPE_INT16
|
#undef TYPE_INT16
|
||||||
|
Loading…
Reference in New Issue
Block a user