зеркало из https://github.com/mozilla/gecko-dev.git
Bug 805080 - Remove unused CESU8 support from SpiderMonkey; r=luke
We have many CESU8 paths in SpiderMonkey which are completely unused and untested. We have many more "UTF-8" paths which are really mislabled CESU8 paths and visa-versa. This patch attempts to disentable all of the various encoding options in SpiderMonkey.
This commit is contained in:
Родитель
b75203c1e9
Коммит
a80f8cc0af
|
@ -597,7 +597,7 @@ ProcessFile(JSContext *cx,
|
|||
}
|
||||
bufp += strlen(bufp);
|
||||
lineno++;
|
||||
} while (!JS_BufferIsCompilableUnit(cx, JS_FALSE, obj, buffer, strlen(buffer)));
|
||||
} while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
|
||||
|
||||
/* Clear any pending exception from previous failed compiles. */
|
||||
JS_ClearPendingException(cx);
|
||||
|
|
|
@ -39,6 +39,114 @@ using namespace std;
|
|||
namespace js {
|
||||
namespace ctypes {
|
||||
|
||||
size_t
|
||||
GetDeflatedUTF8StringLength(JSContext *maybecx, const jschar *chars,
|
||||
size_t nchars)
|
||||
{
|
||||
size_t nbytes;
|
||||
const jschar *end;
|
||||
unsigned c, c2;
|
||||
char buffer[10];
|
||||
|
||||
nbytes = nchars;
|
||||
for (end = chars + nchars; chars != end; chars++) {
|
||||
c = *chars;
|
||||
if (c < 0x80)
|
||||
continue;
|
||||
if (0xD800 <= c && c <= 0xDFFF) {
|
||||
/* Surrogate pair. */
|
||||
chars++;
|
||||
|
||||
/* nbytes sets 1 length since this is surrogate pair. */
|
||||
nbytes--;
|
||||
if (c >= 0xDC00 || chars == end)
|
||||
goto bad_surrogate;
|
||||
c2 = *chars;
|
||||
if (c2 < 0xDC00 || c2 > 0xDFFF)
|
||||
goto bad_surrogate;
|
||||
c = ((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000;
|
||||
}
|
||||
c >>= 11;
|
||||
nbytes++;
|
||||
while (c) {
|
||||
c >>= 5;
|
||||
nbytes++;
|
||||
}
|
||||
}
|
||||
return nbytes;
|
||||
|
||||
bad_surrogate:
|
||||
if (maybecx) {
|
||||
JS_snprintf(buffer, 10, "0x%x", c);
|
||||
JS_ReportErrorFlagsAndNumber(maybecx, JSREPORT_ERROR, js_GetErrorMessage,
|
||||
NULL, JSMSG_BAD_SURROGATE_CHAR, buffer);
|
||||
}
|
||||
return (size_t) -1;
|
||||
}
|
||||
|
||||
bool
|
||||
DeflateStringToUTF8Buffer(JSContext *maybecx, const jschar *src, size_t srclen,
|
||||
char *dst, size_t *dstlenp)
|
||||
{
|
||||
size_t i, utf8Len;
|
||||
jschar c, c2;
|
||||
uint32_t v;
|
||||
uint8_t utf8buf[6];
|
||||
|
||||
size_t dstlen = *dstlenp;
|
||||
size_t origDstlen = dstlen;
|
||||
|
||||
while (srclen) {
|
||||
c = *src++;
|
||||
srclen--;
|
||||
if (c >= 0xDC00 && c <= 0xDFFF)
|
||||
goto badSurrogate;
|
||||
if (c < 0xD800 || c > 0xDBFF) {
|
||||
v = c;
|
||||
} else {
|
||||
if (srclen < 1)
|
||||
goto badSurrogate;
|
||||
c2 = *src;
|
||||
if ((c2 < 0xDC00) || (c2 > 0xDFFF))
|
||||
goto badSurrogate;
|
||||
src++;
|
||||
srclen--;
|
||||
v = ((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000;
|
||||
}
|
||||
if (v < 0x0080) {
|
||||
/* no encoding necessary - performance hack */
|
||||
if (dstlen == 0)
|
||||
goto bufferTooSmall;
|
||||
*dst++ = (char) v;
|
||||
utf8Len = 1;
|
||||
} else {
|
||||
utf8Len = js_OneUcs4ToUtf8Char(utf8buf, v);
|
||||
if (utf8Len > dstlen)
|
||||
goto bufferTooSmall;
|
||||
for (i = 0; i < utf8Len; i++)
|
||||
*dst++ = (char) utf8buf[i];
|
||||
}
|
||||
dstlen -= utf8Len;
|
||||
}
|
||||
*dstlenp = (origDstlen - dstlen);
|
||||
return JS_TRUE;
|
||||
|
||||
badSurrogate:
|
||||
*dstlenp = (origDstlen - dstlen);
|
||||
/* Delegate error reporting to the measurement function. */
|
||||
if (maybecx)
|
||||
GetDeflatedUTF8StringLength(maybecx, src - 1, srclen + 1);
|
||||
return JS_FALSE;
|
||||
|
||||
bufferTooSmall:
|
||||
*dstlenp = (origDstlen - dstlen);
|
||||
if (maybecx) {
|
||||
JS_ReportErrorNumber(maybecx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BUFFER_TOO_SMALL);
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
** JSAPI function prototypes
|
||||
*******************************************************************************/
|
||||
|
|
|
@ -155,6 +155,15 @@ PrependString(Vector<jschar, N, AP> &v, JSString* str)
|
|||
memcpy(v.begin(), chars, alen * sizeof(jschar));
|
||||
}
|
||||
|
||||
extern size_t
|
||||
GetDeflatedUTF8StringLength(JSContext *maybecx, const jschar *chars,
|
||||
size_t charsLength);
|
||||
|
||||
bool
|
||||
DeflateStringToUTF8Buffer(JSContext *maybecx, const jschar *src, size_t srclen,
|
||||
char *dst, size_t *dstlenp);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Function and struct API definitions
|
||||
*******************************************************************************/
|
||||
|
|
|
@ -60,7 +60,6 @@ CPPSRCS = \
|
|||
testStringBuffer.cpp \
|
||||
testTrap.cpp \
|
||||
testTypedArrays.cpp \
|
||||
testUTF8.cpp \
|
||||
testValueABI.cpp \
|
||||
testVersion.cpp \
|
||||
testXDR.cpp \
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
BEGIN_TEST(testUTF8_bug589917)
|
||||
{
|
||||
const jschar surrogate_pair[] = { 0xd800, 0xdc00 };
|
||||
char output_buffer[10];
|
||||
size_t utf8_len = sizeof(output_buffer);
|
||||
|
||||
CHECK(JS_EncodeCharacters(cx, surrogate_pair, 2, output_buffer, &utf8_len));
|
||||
CHECK_EQUAL(utf8_len, 4);
|
||||
|
||||
CHECK(JS_EncodeCharacters(cx, surrogate_pair, 2, NULL, &utf8_len));
|
||||
CHECK_EQUAL(utf8_len, 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testUTF8_bug589917)
|
|
@ -25,10 +25,12 @@ CompileScriptForPrincipalsVersionOrigin(JSContext *cx, JS::HandleObject obj,
|
|||
if (!chars)
|
||||
return NULL;
|
||||
JS_ALWAYS_TRUE(JS_DecodeBytes(cx, bytes, nbytes, chars, &nchars));
|
||||
JSScript *script = JS_CompileUCScriptForPrincipalsVersionOrigin(cx, obj,
|
||||
principals, originPrincipals,
|
||||
chars, nchars,
|
||||
filename, lineno, version);
|
||||
JS::CompileOptions options(cx);
|
||||
options.setPrincipals(principals)
|
||||
.setOriginPrincipals(originPrincipals)
|
||||
.setFileAndLine(filename, lineno)
|
||||
.setVersion(version);
|
||||
JSScript *script = JS::Compile(cx, obj, options, chars, nchars);
|
||||
free(chars);
|
||||
return script;
|
||||
}
|
||||
|
|
|
@ -76,8 +76,6 @@ int main(int argc, char *argv[])
|
|||
int failures = 0;
|
||||
const char *filter = (argc == 2) ? argv[1] : NULL;
|
||||
|
||||
JS_SetCStringsAreUTF8();
|
||||
|
||||
for (JSAPITest *test = JSAPITest::list; test; test = test->next) {
|
||||
const char *name = test->name();
|
||||
if (filter && strstr(name, filter) == NULL)
|
||||
|
|
183
js/src/jsapi.cpp
183
js/src/jsapi.cpp
|
@ -668,9 +668,8 @@ JS_IsBuiltinFunctionConstructor(JSFunction *fun)
|
|||
/************************************************************************/
|
||||
|
||||
/*
|
||||
* Has a new runtime ever been created? This flag is used to detect unsafe
|
||||
* changes to js_CStringsAreUTF8 after a runtime has been created, and to
|
||||
* control things that should happen only once across all runtimes.
|
||||
* Has a new runtime ever been created? This flag is used to control things
|
||||
* that should happen only once across all runtimes.
|
||||
*/
|
||||
static JSBool js_NewRuntimeWasCalled = JS_FALSE;
|
||||
|
||||
|
@ -5211,7 +5210,7 @@ JS::Compile(JSContext *cx, HandleObject obj, CompileOptions options,
|
|||
{
|
||||
jschar *chars;
|
||||
if (options.utf8)
|
||||
chars = InflateString(cx, bytes, &length, CESU8Encoding);
|
||||
chars = InflateUTF8String(cx, bytes, &length);
|
||||
else
|
||||
chars = InflateString(cx, bytes, &length);
|
||||
if (!chars)
|
||||
|
@ -5244,40 +5243,6 @@ JS::Compile(JSContext *cx, HandleObject obj, CompileOptions options, const char
|
|||
return script;
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUCScriptForPrincipalsVersion(JSContext *cx, JSObject *objArg,
|
||||
JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno,
|
||||
JSVersion version)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
CompileOptions options(cx);
|
||||
options.setPrincipals(principals)
|
||||
.setFileAndLine(filename, lineno)
|
||||
.setVersion(version);
|
||||
|
||||
return Compile(cx, obj, options, chars, length);
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUCScriptForPrincipalsVersionOrigin(JSContext *cx, JSObject *objArg,
|
||||
JSPrincipals *principals,
|
||||
JSPrincipals *originPrincipals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno,
|
||||
JSVersion version)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
CompileOptions options(cx);
|
||||
options.setPrincipals(principals)
|
||||
.setOriginPrincipals(originPrincipals)
|
||||
.setFileAndLine(filename, lineno)
|
||||
.setVersion(version);
|
||||
|
||||
return Compile(cx, obj, options, chars, length);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *objArg, JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
|
@ -5302,26 +5267,10 @@ JS_CompileUCScript(JSContext *cx, JSObject *objArg, const jschar *chars, size_t
|
|||
return Compile(cx, obj, options, chars, length);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileScriptForPrincipalsVersion(JSContext *cx, JSObject *objArg,
|
||||
JSPrincipals *principals,
|
||||
const char *bytes, size_t length,
|
||||
const char *filename, unsigned lineno,
|
||||
JSVersion version)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
CompileOptions options(cx);
|
||||
options.setPrincipals(principals)
|
||||
.setFileAndLine(filename, lineno)
|
||||
.setVersion(version);
|
||||
|
||||
return Compile(cx, obj, options, bytes, length);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileScriptForPrincipals(JSContext *cx, JSObject *objArg,
|
||||
JSPrincipals *principals,
|
||||
const char *bytes, size_t length,
|
||||
const char *ascii, size_t length,
|
||||
const char *filename, unsigned lineno)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
|
@ -5329,25 +5278,24 @@ JS_CompileScriptForPrincipals(JSContext *cx, JSObject *objArg,
|
|||
options.setPrincipals(principals)
|
||||
.setFileAndLine(filename, lineno);
|
||||
|
||||
return Compile(cx, obj, options, bytes, length);
|
||||
return Compile(cx, obj, options, ascii, length);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileScript(JSContext *cx, JSObject *objArg, const char *bytes, size_t length,
|
||||
JS_CompileScript(JSContext *cx, JSObject *objArg, const char *ascii, size_t length,
|
||||
const char *filename, unsigned lineno)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
CompileOptions options(cx);
|
||||
options.setFileAndLine(filename, lineno);
|
||||
|
||||
return Compile(cx, obj, options, bytes, length);
|
||||
return Compile(cx, obj, options, ascii, length);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_BufferIsCompilableUnit(JSContext *cx, JSBool bytes_are_utf8, JSObject *objArg, const char *bytes, size_t length)
|
||||
JS_BufferIsCompilableUnit(JSContext *cx, JSObject *objArg, const char *utf8, size_t length)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
jschar *chars;
|
||||
JSBool result;
|
||||
JSExceptionState *exnState;
|
||||
JSErrorReporter older;
|
||||
|
@ -5355,10 +5303,7 @@ JS_BufferIsCompilableUnit(JSContext *cx, JSBool bytes_are_utf8, JSObject *objArg
|
|||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
if (bytes_are_utf8)
|
||||
chars = InflateString(cx, bytes, &length, CESU8Encoding);
|
||||
else
|
||||
chars = InflateString(cx, bytes, &length);
|
||||
jschar *chars = InflateUTF8String(cx, utf8, &length);
|
||||
if (!chars)
|
||||
return JS_TRUE;
|
||||
|
||||
|
@ -5415,20 +5360,6 @@ JS_CompileUTF8FileHandleForPrincipals(JSContext *cx, JSObject *objArg, const cha
|
|||
return Compile(cx, obj, options, file);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUTF8FileHandleForPrincipalsVersion(JSContext *cx, JSObject *objArg, const char *filename,
|
||||
FILE *file, JSPrincipals *principals, JSVersion version)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
CompileOptions options(cx);
|
||||
options.setUTF8(true)
|
||||
.setFileAndLine(filename, 1)
|
||||
.setPrincipals(principals)
|
||||
.setVersion(version);
|
||||
|
||||
return Compile(cx, obj, options, file);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUTF8FileHandle(JSContext *cx, JSObject *objArg, const char *filename, FILE *file)
|
||||
{
|
||||
|
@ -5504,7 +5435,7 @@ JS::CompileFunction(JSContext *cx, HandleObject obj, CompileOptions options,
|
|||
{
|
||||
jschar *chars;
|
||||
if (options.utf8)
|
||||
chars = InflateString(cx, bytes, &length, CESU8Encoding);
|
||||
chars = InflateUTF8String(cx, bytes, &length);
|
||||
else
|
||||
chars = InflateString(cx, bytes, &length);
|
||||
if (!chars)
|
||||
|
@ -5515,39 +5446,6 @@ JS::CompileFunction(JSContext *cx, HandleObject obj, CompileOptions options,
|
|||
return fun;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj_,
|
||||
JSPrincipals *principals, const char *name,
|
||||
unsigned nargs, const char **argnames,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno,
|
||||
JSVersion version)
|
||||
{
|
||||
RootedObject obj(cx, obj_);
|
||||
|
||||
CompileOptions options(cx);
|
||||
options.setPrincipals(principals)
|
||||
.setFileAndLine(filename, lineno)
|
||||
.setVersion(version);
|
||||
|
||||
return CompileFunction(cx, obj, options, name, nargs, argnames, chars, length);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *objArg,
|
||||
JSPrincipals *principals, const char *name,
|
||||
unsigned nargs, const char **argnames,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
CompileOptions options(cx);
|
||||
options.setPrincipals(principals)
|
||||
.setFileAndLine(filename, lineno);
|
||||
|
||||
return CompileFunction(cx, obj, options, name, nargs, argnames, chars, length);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileUCFunction(JSContext *cx, JSObject *objArg, const char *name,
|
||||
unsigned nargs, const char **argnames,
|
||||
|
@ -5565,7 +5463,7 @@ JS_PUBLIC_API(JSFunction *)
|
|||
JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *objArg,
|
||||
JSPrincipals *principals, const char *name,
|
||||
unsigned nargs, const char **argnames,
|
||||
const char *bytes, size_t length,
|
||||
const char *ascii, size_t length,
|
||||
const char *filename, unsigned lineno)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
|
@ -5573,20 +5471,20 @@ JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *objArg,
|
|||
options.setPrincipals(principals)
|
||||
.setFileAndLine(filename, lineno);
|
||||
|
||||
return CompileFunction(cx, obj, options, name, nargs, argnames, bytes, length);
|
||||
return CompileFunction(cx, obj, options, name, nargs, argnames, ascii, length);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileFunction(JSContext *cx, JSObject *objArg, const char *name,
|
||||
unsigned nargs, const char **argnames,
|
||||
const char *bytes, size_t length,
|
||||
const char *ascii, size_t length,
|
||||
const char *filename, unsigned lineno)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
CompileOptions options(cx);
|
||||
options.setFileAndLine(filename, lineno);
|
||||
|
||||
return CompileFunction(cx, obj, options, name, nargs, argnames, bytes, length);
|
||||
return CompileFunction(cx, obj, options, name, nargs, argnames, ascii, length);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
|
@ -5703,7 +5601,7 @@ JS::Evaluate(JSContext *cx, HandleObject obj, CompileOptions options,
|
|||
{
|
||||
jschar *chars;
|
||||
if (options.utf8)
|
||||
chars = InflateString(cx, bytes, &length, CESU8Encoding);
|
||||
chars = InflateUTF8String(cx, bytes, &length);
|
||||
else
|
||||
chars = InflateString(cx, bytes, &length);
|
||||
if (!chars)
|
||||
|
@ -6282,26 +6180,6 @@ JS_UndependString(JSContext *cx, JSString *str)
|
|||
return str->getCharsZ(cx);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char *dst, size_t *dstlenp)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
size_t n;
|
||||
if (!dst) {
|
||||
n = GetDeflatedStringLength(cx, src, srclen);
|
||||
if (n == (size_t)-1) {
|
||||
*dstlenp = 0;
|
||||
return JS_FALSE;
|
||||
}
|
||||
*dstlenp = n;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
return DeflateStringToBuffer(cx, src, srclen, dst, dstlenp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, size_t *dstlenp)
|
||||
{
|
||||
|
@ -6368,11 +6246,7 @@ JS_EncodeStringToBuffer(JSString *str, char *buffer, size_t length)
|
|||
size_t necessaryLength = GetDeflatedStringLength(NULL, chars, str->length());
|
||||
if (necessaryLength == size_t(-1))
|
||||
return size_t(-1);
|
||||
if (writtenLength != length) {
|
||||
/* Make sure that the buffer contains only valid UTF-8 sequences. */
|
||||
JS_ASSERT(js_CStringsAreUTF8);
|
||||
PodZero(buffer + writtenLength, length - writtenLength);
|
||||
}
|
||||
JS_ASSERT(writtenLength == length); // C strings are NOT encoded.
|
||||
return necessaryLength;
|
||||
}
|
||||
|
||||
|
@ -6639,31 +6513,6 @@ JS_WriteBytes(JSStructuredCloneWriter *w, const void *p, size_t len)
|
|||
return w->output().writeBytes(p, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following determines whether C Strings are to be treated as UTF-8
|
||||
* or ISO-8859-1. For correct operation, it must be set prior to the
|
||||
* first call to JS_NewRuntime.
|
||||
*/
|
||||
#ifndef JS_C_STRINGS_ARE_UTF8
|
||||
JSBool js_CStringsAreUTF8 = JS_FALSE;
|
||||
#endif
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_CStringsAreUTF8()
|
||||
{
|
||||
return js_CStringsAreUTF8;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetCStringsAreUTF8()
|
||||
{
|
||||
JS_ASSERT(!js_NewRuntimeWasCalled);
|
||||
|
||||
#ifndef JS_C_STRINGS_ARE_UTF8
|
||||
js_CStringsAreUTF8 = JS_TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
|
|
@ -1974,7 +1974,7 @@ typedef enum JSExnType {
|
|||
} JSExnType;
|
||||
|
||||
typedef struct JSErrorFormatString {
|
||||
/* The error format string (UTF-8 if js_CStringsAreUTF8). */
|
||||
/* The error format string in ASCII. */
|
||||
const char *format;
|
||||
|
||||
/* The number of arguments to expand in the formatted error message. */
|
||||
|
@ -4948,27 +4948,19 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSRawObject parent);
|
|||
* the compiler.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_BufferIsCompilableUnit(JSContext *cx, JSBool bytes_are_utf8,
|
||||
JSObject *obj, const char *bytes, size_t length);
|
||||
JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj, const char *utf8, size_t length);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileScript(JSContext *cx, JSObject *obj,
|
||||
const char *bytes, size_t length,
|
||||
const char *ascii, size_t length,
|
||||
const char *filename, unsigned lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const char *bytes, size_t length,
|
||||
const char *ascii, size_t length,
|
||||
const char *filename, unsigned lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const char *bytes, size_t length,
|
||||
const char *filename, unsigned lineno,
|
||||
JSVersion version);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUCScript(JSContext *cx, JSObject *obj,
|
||||
const jschar *chars, size_t length,
|
||||
|
@ -4980,24 +4972,6 @@ JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
|
|||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno,
|
||||
JSVersion version);
|
||||
/*
|
||||
* If originPrincipals is null, then the value of principals is used as origin
|
||||
* principals for the compiled script.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUCScriptForPrincipalsVersionOrigin(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
JSPrincipals *originPrincipals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno,
|
||||
JSVersion version);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUTF8File(JSContext *cx, JSObject *obj, const char *filename);
|
||||
|
||||
|
@ -5010,12 +4984,6 @@ JS_CompileUTF8FileHandleForPrincipals(JSContext *cx, JSObject *obj,
|
|||
const char *filename, FILE *fh,
|
||||
JSPrincipals *principals);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileUTF8FileHandleForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
const char *filename, FILE *fh,
|
||||
JSPrincipals *principals,
|
||||
JSVersion version);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetGlobalFromScript(JSScript *script);
|
||||
|
||||
|
@ -5038,21 +5006,6 @@ JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name,
|
|||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals, const char *name,
|
||||
unsigned nargs, const char **argnames,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals, const char *name,
|
||||
unsigned nargs, const char **argnames,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, unsigned lineno,
|
||||
JSVersion version);
|
||||
|
||||
#ifdef __cplusplus
|
||||
JS_END_EXTERN_C
|
||||
|
||||
|
@ -5537,48 +5490,19 @@ extern JS_PUBLIC_API(const jschar *)
|
|||
JS_UndependString(JSContext *cx, JSString *str);
|
||||
|
||||
/*
|
||||
* Return JS_TRUE if C (char []) strings passed via the API and internally
|
||||
* are UTF-8.
|
||||
*/
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_CStringsAreUTF8(void);
|
||||
|
||||
/*
|
||||
* Update the value to be returned by JS_CStringsAreUTF8(). Once set, it
|
||||
* can never be changed. This API must be called before the first call to
|
||||
* JS_NewRuntime.
|
||||
*/
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetCStringsAreUTF8(void);
|
||||
|
||||
/*
|
||||
* Character encoding support.
|
||||
*
|
||||
* For both JS_EncodeCharacters and JS_DecodeBytes, set *dstlenp to the size
|
||||
* of the destination buffer before the call; on return, *dstlenp contains the
|
||||
* number of bytes (JS_EncodeCharacters) or jschars (JS_DecodeBytes) actually
|
||||
* stored. To determine the necessary destination buffer size, make a sizing
|
||||
* call that passes NULL for dst.
|
||||
* For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before
|
||||
* the call; on return, *dstlenp contains the number of jschars actually stored.
|
||||
* To determine the necessary destination buffer size, make a sizing call that
|
||||
* passes NULL for dst.
|
||||
*
|
||||
* On errors, the functions report the error. In that case, *dstlenp contains
|
||||
* the number of characters or bytes transferred so far. If cx is NULL, no
|
||||
* error is reported on failure, and the functions simply return JS_FALSE.
|
||||
*
|
||||
* NB: Neither function stores an additional zero byte or jschar after the
|
||||
* NB: This function does not store an additional zero byte or jschar after the
|
||||
* transcoded string.
|
||||
*
|
||||
* If JS_CStringsAreUTF8() is true then JS_EncodeCharacters encodes to
|
||||
* UTF-8, and JS_DecodeBytes decodes from UTF-8, which may create additional
|
||||
* errors if the character sequence is malformed. If UTF-8 support is
|
||||
* disabled, the functions deflate and inflate, respectively.
|
||||
*
|
||||
* JS_DecodeUTF8() always behaves the same independently of JS_CStringsAreUTF8().
|
||||
*/
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char *dst,
|
||||
size_t *dstlenp);
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst,
|
||||
size_t *dstlenp);
|
||||
|
||||
|
@ -5608,11 +5532,6 @@ JS_GetStringEncodingLength(JSContext *cx, JSString *str);
|
|||
* of bytes that are necessary to encode the string. If that exceeds the
|
||||
* length parameter, the string will be cut and only length bytes will be
|
||||
* written into the buffer.
|
||||
*
|
||||
* If JS_CStringsAreUTF8() is true, the string does not fit into the buffer
|
||||
* and the the first length bytes ends in the middle of utf-8 encoding for
|
||||
* some character, then such partial utf-8 encoding is replaced by zero bytes.
|
||||
* This way the result always represents the valid UTF-8 sequence.
|
||||
*/
|
||||
JS_PUBLIC_API(size_t)
|
||||
JS_EncodeStringToBuffer(JSString *str, char *buffer, size_t length);
|
||||
|
|
|
@ -319,7 +319,7 @@ js::AtomizeString(JSContext *cx, JSString *str, InternBehavior ib)
|
|||
}
|
||||
|
||||
JSAtom *
|
||||
js::Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib, FlationCoding fc)
|
||||
js::Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
|
@ -340,15 +340,12 @@ js::Atomize(JSContext *cx, const char *bytes, size_t length, InternBehavior ib,
|
|||
const jschar *chars;
|
||||
OwnCharsBehavior ocb = CopyChars;
|
||||
if (length < ATOMIZE_BUF_MAX) {
|
||||
if (fc == CESU8Encoding)
|
||||
InflateUTF8StringToBuffer(cx, bytes, length, inflated, &inflatedLength, fc);
|
||||
else
|
||||
InflateStringToBuffer(cx, bytes, length, inflated, &inflatedLength);
|
||||
InflateStringToBuffer(cx, bytes, length, inflated, &inflatedLength);
|
||||
inflated[inflatedLength] = 0;
|
||||
chars = inflated;
|
||||
} else {
|
||||
inflatedLength = length;
|
||||
chars = InflateString(cx, bytes, &inflatedLength, fc);
|
||||
chars = InflateString(cx, bytes, &inflatedLength);
|
||||
if (!chars)
|
||||
return NULL;
|
||||
ocb = TakeCharOwnership;
|
||||
|
|
|
@ -119,29 +119,6 @@ struct AtomHasher
|
|||
|
||||
typedef HashSet<AtomStateEntry, AtomHasher, SystemAllocPolicy> AtomSet;
|
||||
|
||||
/*
|
||||
* On encodings:
|
||||
*
|
||||
* - Some string functions have an optional FlationCoding argument that allow
|
||||
* the caller to force CESU-8 encoding handling.
|
||||
* - Functions that don't take a FlationCoding base their NormalEncoding
|
||||
* behavior on the js_CStringsAreUTF8 value. NormalEncoding is either raw
|
||||
* (simple zero-extension) or UTF-8 depending on js_CStringsAreUTF8.
|
||||
* - Functions that explicitly state their encoding do not use the
|
||||
* js_CStringsAreUTF8 value.
|
||||
*
|
||||
* CESU-8 (Compatibility Encoding Scheme for UTF-16: 8-bit) is a variant of
|
||||
* UTF-8 that allows us to store any wide character string as a narrow
|
||||
* character string. For strings containing mostly ascii, it saves space.
|
||||
* http://www.unicode.org/reports/tr26/
|
||||
*/
|
||||
|
||||
enum FlationCoding
|
||||
{
|
||||
NormalEncoding,
|
||||
CESU8Encoding
|
||||
};
|
||||
|
||||
class PropertyName;
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -246,8 +223,7 @@ enum InternBehavior
|
|||
|
||||
extern JSAtom *
|
||||
Atomize(JSContext *cx, const char *bytes, size_t length,
|
||||
js::InternBehavior ib = js::DoNotInternAtom,
|
||||
js::FlationCoding fc = js::NormalEncoding);
|
||||
js::InternBehavior ib = js::DoNotInternAtom);
|
||||
|
||||
extern JSAtom *
|
||||
AtomizeChars(JSContext *cx, const jschar *chars, size_t length,
|
||||
|
|
|
@ -668,8 +668,6 @@ 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 . */
|
||||
uint8_t utf8buf[6];
|
||||
int utf8len;
|
||||
|
||||
/*
|
||||
** build an argument array, IF the fmt is numbered argument
|
||||
|
@ -906,13 +904,6 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
|
|||
}
|
||||
switch (type) {
|
||||
case TYPE_INT16:
|
||||
/* Treat %hc as %c unless js_CStringsAreUTF8. */
|
||||
if (js_CStringsAreUTF8) {
|
||||
u.wch = va_arg(ap, int);
|
||||
utf8len = js_OneUcs4ToUtf8Char (utf8buf, u.wch);
|
||||
rv = (*ss->stuff)(ss, (char *)utf8buf, utf8len);
|
||||
break;
|
||||
}
|
||||
case TYPE_INTN:
|
||||
u.ch = va_arg(ap, int);
|
||||
rv = (*ss->stuff)(ss, &u.ch, 1);
|
||||
|
@ -957,10 +948,6 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
|
|||
|
||||
case 's':
|
||||
if(type == TYPE_INT16) {
|
||||
/*
|
||||
* This would do a simple string/byte conversion
|
||||
* unless js_CStringsAreUTF8.
|
||||
*/
|
||||
u.ws = va_arg(ap, const jschar*);
|
||||
rv = cvt_ws(ss, u.ws, width, prec, flags);
|
||||
} else {
|
||||
|
|
|
@ -16,10 +16,9 @@
|
|||
** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above
|
||||
** %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 js_CStringsAreUTF8)
|
||||
** %s - ascii string
|
||||
** %hs - ucs2 string
|
||||
** %c - character
|
||||
** %hc - 16-bit version of above (only available if js_CStringsAreUTF8)
|
||||
** %p - pointer (deals with machine dependent pointer size)
|
||||
** %f - float
|
||||
** %g - float
|
||||
|
|
|
@ -379,16 +379,6 @@ typedef JSObject *
|
|||
typedef JSObject *
|
||||
(* JSIteratorOp)(JSContext *cx, JSHandleObject obj, JSBool keysonly);
|
||||
|
||||
/*
|
||||
* The following determines whether JS_EncodeCharacters and JS_DecodeBytes
|
||||
* treat char[] as utf-8 or simply as bytes that need to be inflated/deflated.
|
||||
*/
|
||||
#ifdef JS_C_STRINGS_ARE_UTF8
|
||||
# define js_CStringsAreUTF8 JS_TRUE
|
||||
#else
|
||||
extern JSBool js_CStringsAreUTF8;
|
||||
#endif
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsprvtd_h___ */
|
||||
|
|
271
js/src/jsstr.cpp
271
js/src/jsstr.cpp
|
@ -3297,23 +3297,11 @@ NewShortString(JSContext *cx, const char *chars, size_t length)
|
|||
if (!str)
|
||||
return NULL;
|
||||
|
||||
jschar *storage = str->init(length);
|
||||
if (js_CStringsAreUTF8) {
|
||||
#ifdef DEBUG
|
||||
size_t oldLength = length;
|
||||
#endif
|
||||
if (!InflateUTF8StringToBuffer(cx, chars, length, storage, &length))
|
||||
return NULL;
|
||||
JS_ASSERT(length <= oldLength);
|
||||
storage[length] = 0;
|
||||
str->resetLength(length);
|
||||
} else {
|
||||
size_t n = length;
|
||||
jschar *p = storage;
|
||||
while (n--)
|
||||
*p++ = (unsigned char)*chars++;
|
||||
*p = 0;
|
||||
}
|
||||
size_t n = length;
|
||||
jschar *p = str->init(length);
|
||||
while (n--)
|
||||
*p++ = (unsigned char)*chars++;
|
||||
*p = 0;
|
||||
Probes::createString(cx, str, length);
|
||||
return str;
|
||||
}
|
||||
|
@ -3615,7 +3603,34 @@ js_strchr_limit(const jschar *s, jschar c, const jschar *limit)
|
|||
namespace js {
|
||||
|
||||
jschar *
|
||||
InflateString(JSContext *cx, const char *bytes, size_t *lengthp, FlationCoding fc)
|
||||
InflateString(JSContext *cx, const char *bytes, size_t *lengthp)
|
||||
{
|
||||
AssertCanGC();
|
||||
size_t nchars;
|
||||
jschar *chars;
|
||||
size_t nbytes = *lengthp;
|
||||
|
||||
nchars = nbytes;
|
||||
chars = cx->pod_malloc<jschar>(nchars + 1);
|
||||
if (!chars)
|
||||
goto bad;
|
||||
for (size_t i = 0; i < nchars; i++)
|
||||
chars[i] = (unsigned char) bytes[i];
|
||||
*lengthp = nchars;
|
||||
chars[nchars] = 0;
|
||||
return chars;
|
||||
|
||||
bad:
|
||||
/*
|
||||
* For compatibility with callers of JS_DecodeBytes we must zero lengthp
|
||||
* on errors.
|
||||
*/
|
||||
*lengthp = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jschar *
|
||||
InflateUTF8String(JSContext *cx, const char *bytes, size_t *lengthp)
|
||||
{
|
||||
AssertCanGC();
|
||||
size_t nchars;
|
||||
|
@ -3625,21 +3640,12 @@ InflateString(JSContext *cx, const char *bytes, size_t *lengthp, FlationCoding f
|
|||
// Malformed UTF8 chars could trigger errors and hence GC
|
||||
MaybeCheckStackRoots(cx);
|
||||
|
||||
if (js_CStringsAreUTF8 || fc == CESU8Encoding) {
|
||||
if (!InflateUTF8StringToBuffer(cx, bytes, nbytes, NULL, &nchars, fc))
|
||||
goto bad;
|
||||
chars = cx->pod_malloc<jschar>(nchars + 1);
|
||||
if (!chars)
|
||||
goto bad;
|
||||
JS_ALWAYS_TRUE(InflateUTF8StringToBuffer(cx, bytes, nbytes, chars, &nchars, fc));
|
||||
} else {
|
||||
nchars = nbytes;
|
||||
chars = cx->pod_malloc<jschar>(nchars + 1);
|
||||
if (!chars)
|
||||
goto bad;
|
||||
for (size_t i = 0; i < nchars; i++)
|
||||
chars[i] = (unsigned char) bytes[i];
|
||||
}
|
||||
if (!InflateUTF8StringToBuffer(cx, bytes, nbytes, NULL, &nchars))
|
||||
goto bad;
|
||||
chars = cx->pod_malloc<jschar>(nchars + 1);
|
||||
if (!chars)
|
||||
goto bad;
|
||||
JS_ALWAYS_TRUE(InflateUTF8StringToBuffer(cx, bytes, nbytes, chars, &nchars));
|
||||
*lengthp = nchars;
|
||||
chars[nchars] = 0;
|
||||
return chars;
|
||||
|
@ -3657,27 +3663,17 @@ InflateString(JSContext *cx, const char *bytes, size_t *lengthp, FlationCoding f
|
|||
* May be called with null cx.
|
||||
*/
|
||||
char *
|
||||
DeflateString(JSContext *cx, const jschar *chars, size_t nchars)
|
||||
DeflateString(JSContext *maybecx, const jschar *chars, size_t nchars)
|
||||
{
|
||||
size_t nbytes, i;
|
||||
char *bytes;
|
||||
|
||||
if (js_CStringsAreUTF8) {
|
||||
nbytes = GetDeflatedStringLength(cx, chars, nchars);
|
||||
if (nbytes == (size_t) -1)
|
||||
return NULL;
|
||||
bytes = (char *) (cx ? cx->malloc_(nbytes + 1) : js_malloc(nbytes + 1));
|
||||
if (!bytes)
|
||||
return NULL;
|
||||
JS_ALWAYS_TRUE(DeflateStringToBuffer(cx, chars, nchars, bytes, &nbytes));
|
||||
} else {
|
||||
nbytes = nchars;
|
||||
bytes = (char *) (cx ? cx->malloc_(nbytes + 1) : js_malloc(nbytes + 1));
|
||||
if (!bytes)
|
||||
return NULL;
|
||||
for (i = 0; i < nbytes; i++)
|
||||
bytes[i] = (char) chars[i];
|
||||
}
|
||||
AutoAssertNoGC nogc;
|
||||
size_t nbytes = nchars;
|
||||
char *bytes = maybecx
|
||||
? maybecx->pod_malloc<char>(nbytes + 1)
|
||||
: js_pod_malloc<char>(nbytes + 1);
|
||||
if (!bytes)
|
||||
return NULL;
|
||||
for (size_t i = 0; i < nbytes; i++)
|
||||
bytes[i] = (char) chars[i];
|
||||
bytes[nbytes] = 0;
|
||||
return bytes;
|
||||
}
|
||||
|
@ -3685,172 +3681,46 @@ DeflateString(JSContext *cx, const jschar *chars, size_t nchars)
|
|||
size_t
|
||||
GetDeflatedStringLength(JSContext *cx, const jschar *chars, size_t nchars)
|
||||
{
|
||||
if (!js_CStringsAreUTF8)
|
||||
return nchars;
|
||||
|
||||
return GetDeflatedUTF8StringLength(cx, chars, nchars);
|
||||
}
|
||||
|
||||
/*
|
||||
* May be called with null cx through public API, see below.
|
||||
*/
|
||||
size_t
|
||||
GetDeflatedUTF8StringLength(JSContext *cx, const jschar *chars,
|
||||
size_t nchars, FlationCoding fc)
|
||||
{
|
||||
size_t nbytes;
|
||||
const jschar *end;
|
||||
unsigned c, c2;
|
||||
char buffer[10];
|
||||
bool useCESU8 = fc == CESU8Encoding;
|
||||
|
||||
nbytes = nchars;
|
||||
for (end = chars + nchars; chars != end; chars++) {
|
||||
c = *chars;
|
||||
if (c < 0x80)
|
||||
continue;
|
||||
if (0xD800 <= c && c <= 0xDFFF && !useCESU8) {
|
||||
/* Surrogate pair. */
|
||||
chars++;
|
||||
|
||||
/* nbytes sets 1 length since this is surrogate pair. */
|
||||
nbytes--;
|
||||
if (c >= 0xDC00 || chars == end)
|
||||
goto bad_surrogate;
|
||||
c2 = *chars;
|
||||
if (c2 < 0xDC00 || c2 > 0xDFFF)
|
||||
goto bad_surrogate;
|
||||
c = ((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000;
|
||||
}
|
||||
c >>= 11;
|
||||
nbytes++;
|
||||
while (c) {
|
||||
c >>= 5;
|
||||
nbytes++;
|
||||
}
|
||||
}
|
||||
return nbytes;
|
||||
|
||||
bad_surrogate:
|
||||
if (cx) {
|
||||
JS_snprintf(buffer, 10, "0x%x", c);
|
||||
JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage,
|
||||
NULL, JSMSG_BAD_SURROGATE_CHAR, buffer);
|
||||
}
|
||||
return (size_t) -1;
|
||||
return nchars;
|
||||
}
|
||||
|
||||
bool
|
||||
DeflateStringToBuffer(JSContext *cx, const jschar *src, size_t srclen,
|
||||
DeflateStringToBuffer(JSContext *maybecx, const jschar *src, size_t srclen,
|
||||
char *dst, size_t *dstlenp)
|
||||
{
|
||||
size_t dstlen, i;
|
||||
|
||||
dstlen = *dstlenp;
|
||||
if (!js_CStringsAreUTF8) {
|
||||
if (srclen > dstlen) {
|
||||
for (i = 0; i < dstlen; i++)
|
||||
dst[i] = (char) src[i];
|
||||
if (cx) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BUFFER_TOO_SMALL);
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
for (i = 0; i < srclen; i++)
|
||||
dst[i] = (char) src[i];
|
||||
*dstlenp = srclen;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
return DeflateStringToUTF8Buffer(cx, src, srclen, dst, dstlenp);
|
||||
}
|
||||
|
||||
bool
|
||||
DeflateStringToUTF8Buffer(JSContext *cx, const jschar *src, size_t srclen,
|
||||
char *dst, size_t *dstlenp, FlationCoding fc)
|
||||
{
|
||||
size_t i, utf8Len;
|
||||
jschar c, c2;
|
||||
uint32_t v;
|
||||
uint8_t utf8buf[6];
|
||||
|
||||
bool useCESU8 = fc == CESU8Encoding;
|
||||
size_t dstlen = *dstlenp;
|
||||
size_t origDstlen = dstlen;
|
||||
|
||||
while (srclen) {
|
||||
c = *src++;
|
||||
srclen--;
|
||||
if ((c >= 0xDC00) && (c <= 0xDFFF) && !useCESU8)
|
||||
goto badSurrogate;
|
||||
if (c < 0xD800 || c > 0xDBFF || useCESU8) {
|
||||
v = c;
|
||||
} else {
|
||||
if (srclen < 1)
|
||||
goto badSurrogate;
|
||||
c2 = *src;
|
||||
if ((c2 < 0xDC00) || (c2 > 0xDFFF))
|
||||
goto badSurrogate;
|
||||
src++;
|
||||
srclen--;
|
||||
v = ((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000;
|
||||
if (srclen > dstlen) {
|
||||
for (size_t i = 0; i < dstlen; i++)
|
||||
dst[i] = (char) src[i];
|
||||
if (maybecx) {
|
||||
JS_ReportErrorNumber(maybecx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BUFFER_TOO_SMALL);
|
||||
}
|
||||
if (v < 0x0080) {
|
||||
/* no encoding necessary - performance hack */
|
||||
if (dstlen == 0)
|
||||
goto bufferTooSmall;
|
||||
*dst++ = (char) v;
|
||||
utf8Len = 1;
|
||||
} else {
|
||||
utf8Len = js_OneUcs4ToUtf8Char(utf8buf, v);
|
||||
if (utf8Len > dstlen)
|
||||
goto bufferTooSmall;
|
||||
for (i = 0; i < utf8Len; i++)
|
||||
*dst++ = (char) utf8buf[i];
|
||||
}
|
||||
dstlen -= utf8Len;
|
||||
return JS_FALSE;
|
||||
}
|
||||
*dstlenp = (origDstlen - dstlen);
|
||||
for (size_t i = 0; i < srclen; i++)
|
||||
dst[i] = (char) src[i];
|
||||
*dstlenp = srclen;
|
||||
return JS_TRUE;
|
||||
|
||||
badSurrogate:
|
||||
*dstlenp = (origDstlen - dstlen);
|
||||
/* Delegate error reporting to the measurement function. */
|
||||
if (cx)
|
||||
GetDeflatedStringLength(cx, src - 1, srclen + 1);
|
||||
return JS_FALSE;
|
||||
|
||||
bufferTooSmall:
|
||||
*dstlenp = (origDstlen - dstlen);
|
||||
if (cx) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BUFFER_TOO_SMALL);
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
InflateStringToBuffer(JSContext *cx, const char *src, size_t srclen,
|
||||
InflateStringToBuffer(JSContext *maybecx, const char *src, size_t srclen,
|
||||
jschar *dst, size_t *dstlenp)
|
||||
{
|
||||
size_t dstlen, i;
|
||||
|
||||
if (js_CStringsAreUTF8)
|
||||
return InflateUTF8StringToBuffer(cx, src, srclen, dst, dstlenp);
|
||||
|
||||
if (dst) {
|
||||
dstlen = *dstlenp;
|
||||
size_t dstlen = *dstlenp;
|
||||
if (srclen > dstlen) {
|
||||
for (i = 0; i < dstlen; i++)
|
||||
for (size_t i = 0; i < dstlen; i++)
|
||||
dst[i] = (unsigned char) src[i];
|
||||
if (cx) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
if (maybecx) {
|
||||
JS_ReportErrorNumber(maybecx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BUFFER_TOO_SMALL);
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
for (i = 0; i < srclen; i++)
|
||||
for (size_t i = 0; i < srclen; i++)
|
||||
dst[i] = (unsigned char) src[i];
|
||||
}
|
||||
*dstlenp = srclen;
|
||||
|
@ -3859,7 +3729,7 @@ InflateStringToBuffer(JSContext *cx, const char *src, size_t srclen,
|
|||
|
||||
bool
|
||||
InflateUTF8StringToBuffer(JSContext *cx, const char *src, size_t srclen,
|
||||
jschar *dst, size_t *dstlenp, FlationCoding fc)
|
||||
jschar *dst, size_t *dstlenp)
|
||||
{
|
||||
size_t dstlen, origDstlen, offset, j, n;
|
||||
uint32_t v;
|
||||
|
@ -3867,7 +3737,6 @@ InflateUTF8StringToBuffer(JSContext *cx, const char *src, size_t srclen,
|
|||
dstlen = dst ? *dstlenp : (size_t) -1;
|
||||
origDstlen = dstlen;
|
||||
offset = 0;
|
||||
bool useCESU8 = fc == CESU8Encoding;
|
||||
|
||||
while (srclen) {
|
||||
v = (uint8_t) *src;
|
||||
|
@ -3884,7 +3753,7 @@ InflateUTF8StringToBuffer(JSContext *cx, const char *src, size_t srclen,
|
|||
goto badCharacter;
|
||||
}
|
||||
v = Utf8ToOneUcs4Char((uint8_t *)src, n);
|
||||
if (v >= 0x10000 && !useCESU8) {
|
||||
if (v >= 0x10000) {
|
||||
v -= 0x10000;
|
||||
if (v > 0xFFFFF || dstlen < 2) {
|
||||
*dstlenp = (origDstlen - dstlen);
|
||||
|
|
|
@ -208,13 +208,20 @@ js_strdup(JSContext *cx, const jschar *s);
|
|||
namespace js {
|
||||
|
||||
/*
|
||||
* Inflate bytes to jschars. Return null on error, otherwise return the jschar
|
||||
* or byte vector that was malloc'ed. length is updated to the length of the
|
||||
* Inflate bytes in ASCII encoding to jschars. Return null on error, otherwise
|
||||
* return the jschar that was malloc'ed. length is updated to the length of the
|
||||
* new string (in jschars).
|
||||
*/
|
||||
extern jschar *
|
||||
InflateString(JSContext *cx, const char *bytes, size_t *length,
|
||||
FlationCoding fc = NormalEncoding);
|
||||
InflateString(JSContext *cx, const char *bytes, size_t *length);
|
||||
|
||||
/*
|
||||
* Inflate bytes in UTF-8 encoding to jschars. Return null on error, otherwise
|
||||
* return the jschar vector that was malloc'ed. length is updated to the length
|
||||
* of the new string (in jschars).
|
||||
*/
|
||||
extern jschar *
|
||||
InflateUTF8String(JSContext *cx, const char *bytes, size_t *length);
|
||||
|
||||
extern char *
|
||||
DeflateString(JSContext *cx, const jschar *chars, size_t length);
|
||||
|
@ -232,37 +239,22 @@ InflateStringToBuffer(JSContext *cx, const char *bytes, size_t length,
|
|||
|
||||
extern bool
|
||||
InflateUTF8StringToBuffer(JSContext *cx, const char *bytes, size_t length,
|
||||
jschar *chars, size_t *charsLength,
|
||||
FlationCoding fc = NormalEncoding);
|
||||
jschar *chars, size_t *charsLength);
|
||||
|
||||
/* Get number of bytes in the deflated sequence of characters. */
|
||||
extern size_t
|
||||
GetDeflatedStringLength(JSContext *cx, const jschar *chars, size_t charsLength);
|
||||
|
||||
/* This function will never fail (return -1) in CESU-8 mode. */
|
||||
extern size_t
|
||||
GetDeflatedUTF8StringLength(JSContext *cx, const jschar *chars,
|
||||
size_t charsLength,
|
||||
FlationCoding fc = NormalEncoding);
|
||||
|
||||
/*
|
||||
* Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for
|
||||
* 'length chars. The buffer is NOT null-terminated. The destination length
|
||||
* must to be initialized with the buffer size and will contain on return the
|
||||
* number of copied bytes. Conversion behavior depends on js_CStringsAreUTF8.
|
||||
* number of copied bytes.
|
||||
*/
|
||||
extern bool
|
||||
DeflateStringToBuffer(JSContext *cx, const jschar *chars,
|
||||
size_t charsLength, char *bytes, size_t *length);
|
||||
|
||||
/*
|
||||
* Same as DeflateStringToBuffer, but treats 'bytes' as UTF-8 or CESU-8.
|
||||
*/
|
||||
extern bool
|
||||
DeflateStringToUTF8Buffer(JSContext *cx, const jschar *chars,
|
||||
size_t charsLength, char *bytes, size_t *length,
|
||||
FlationCoding fc = NormalEncoding);
|
||||
|
||||
/*
|
||||
* The String.prototype.replace fast-native entry point is exported for joined
|
||||
* function optimization in js{interp,tracer}.cpp.
|
||||
|
|
|
@ -359,9 +359,6 @@ SetContextOptions(JSContext *cx)
|
|||
static void
|
||||
SkipUTF8BOM(FILE* file)
|
||||
{
|
||||
if (!js_CStringsAreUTF8)
|
||||
return;
|
||||
|
||||
int ch1 = fgetc(file);
|
||||
int ch2 = fgetc(file);
|
||||
int ch3 = fgetc(file);
|
||||
|
@ -509,7 +506,7 @@ Process(JSContext *cx, JSObject *obj_, const char *filename, bool forceTTY)
|
|||
hitEOF = true;
|
||||
break;
|
||||
}
|
||||
} while (!JS_BufferIsCompilableUnit(cx, true, obj, buffer, len));
|
||||
} while (!JS_BufferIsCompilableUnit(cx, obj, buffer, len));
|
||||
|
||||
if (hitEOF && !buffer)
|
||||
break;
|
||||
|
@ -2300,13 +2297,6 @@ ToInt32(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
StringsAreUTF8(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
*vp = JS_CStringsAreUTF8() ? JSVAL_TRUE : JSVAL_FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char* badUTF8 = "...\xC0...";
|
||||
static const char* bigUTF8 = "...\xFB\xBF\xBF\xBF\xBF...";
|
||||
static const jschar badSurrogate[] = { 'A', 'B', 'C', 0xDEEE, 'D', 'E', 0 };
|
||||
|
@ -2334,7 +2324,7 @@ TestUTF8(JSContext *cx, unsigned argc, jsval *vp)
|
|||
break;
|
||||
/* mode 3: bad surrogate character. */
|
||||
case 3:
|
||||
JS_EncodeCharacters(cx, badSurrogate, 6, bytes, &bytesLength);
|
||||
DeflateStringToBuffer(cx, badSurrogate, 6, bytes, &bytesLength);
|
||||
break;
|
||||
/* mode 4: use a too small buffer. */
|
||||
case 4:
|
||||
|
@ -3541,10 +3531,6 @@ static JSFunctionSpecWithHelp shell_functions[] = {
|
|||
"pc2line(fun[, pc])",
|
||||
" Map PC to line number."),
|
||||
|
||||
JS_FN_HELP("stringsAreUTF8", StringsAreUTF8, 0, 0,
|
||||
"stringsAreUTF8()",
|
||||
" Check if strings are UTF-8 encoded."),
|
||||
|
||||
JS_FN_HELP("testUTF8", TestUTF8, 1, 0,
|
||||
"testUTF8(mode)",
|
||||
" Perform UTF-8 tests (modes are 1 to 4)."),
|
||||
|
@ -4873,7 +4859,6 @@ main(int argc, char **argv, char **envp)
|
|||
|| !op.addIntOption('A', "oom-after", "COUNT", "Trigger OOM after COUNT allocations", -1)
|
||||
|| !op.addBoolOption('O', "print-alloc", "Print the number of allocations at exit")
|
||||
#endif
|
||||
|| !op.addBoolOption('U', "utf8", "C strings passed to the JSAPI are UTF-8 encoded")
|
||||
|| !op.addOptionalStringArg("script", "A script to execute (after all options)")
|
||||
|| !op.addOptionalMultiStringArg("scriptArgs",
|
||||
"String arguments to bind as |arguments| in the "
|
||||
|
@ -4938,10 +4923,6 @@ main(int argc, char **argv, char **envp)
|
|||
OOM_printAllocationCount = true;
|
||||
#endif
|
||||
|
||||
/* Must be done before we create the JSRuntime. */
|
||||
if (op.getBoolOption('U'))
|
||||
JS_SetCStringsAreUTF8();
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Set the timer calibration delay count to 0 so we get high
|
||||
// resolution right away, which we need for precise benchmarking.
|
||||
|
|
|
@ -146,19 +146,5 @@ function test()
|
|||
reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
|
||||
}
|
||||
|
||||
for (var i=5; i<=9; i++)
|
||||
status = summary + ': UTF-8 test: bad UTF-8 sequence ' + i;
|
||||
expect = 'Error';
|
||||
actual = 'No error!';
|
||||
try
|
||||
{
|
||||
testUTF8(i);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
actual = 'Error';
|
||||
}
|
||||
reportCompare(expect, actual, status);
|
||||
|
||||
exitFunc('test');
|
||||
}
|
||||
|
|
|
@ -4607,7 +4607,7 @@ DebuggerEnv_getType(JSContext *cx, unsigned argc, Value *vp)
|
|||
else
|
||||
s = "object";
|
||||
|
||||
JSAtom *str = Atomize(cx, s, strlen(s), InternAtom, NormalEncoding);
|
||||
JSAtom *str = Atomize(cx, s, strlen(s), InternAtom);
|
||||
if (!str)
|
||||
return false;
|
||||
args.rval().setString(str);
|
||||
|
|
|
@ -1039,7 +1039,7 @@ ProcessFile(JSContext *cx, JSObject *obj, const char *filename, FILE *file,
|
|||
}
|
||||
bufp += strlen(bufp);
|
||||
lineno++;
|
||||
} while (!JS_BufferIsCompilableUnit(cx, false, obj, buffer, strlen(buffer)));
|
||||
} while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
|
||||
|
||||
DoBeginRequest(cx);
|
||||
/* Clear any pending exception from previous failed compiles. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче