Bug 811060 - Move DeflateString out of jsstr and make it Typey; r=Waldo

--HG--
extra : rebase_source : 9d239c525e8b0c04a63770d4ed732c9c6da54a2c
This commit is contained in:
Terrence Cole 2012-11-09 09:45:25 -08:00
parent 7845a8d5e0
commit b97ee61fd5
22 changed files with 283 additions and 241 deletions

View File

@ -915,19 +915,20 @@ jsdProperty::GetValue(jsdIValue **_rval)
NS_IMPL_THREADSAFE_ISUPPORTS2(jsdScript, jsdIScript, jsdIEphemeral)
static NS_IMETHODIMP
AssignToJSString(nsACString *x, JSString *str)
AssignToJSString(JSDContext *aCx, nsACString *x, JSString *str)
{
if (!str) {
x->SetLength(0);
return NS_OK;
}
size_t length = JS_GetStringEncodingLength(NULL, str);
JSContext *cx = JSD_GetDefaultJSContext(aCx);
size_t length = JS_GetStringEncodingLength(cx, str);
if (length == size_t(-1))
return NS_ERROR_FAILURE;
x->SetLength(uint32_t(length));
if (x->Length() != uint32_t(length))
return NS_ERROR_OUT_OF_MEMORY;
JS_EncodeStringToBuffer(str, x->BeginWriting(), length);
JS_EncodeStringToBuffer(cx, str, x->BeginWriting(), length);
return NS_OK;
}
@ -953,7 +954,7 @@ jsdScript::jsdScript (JSDContext *aCx, JSDScript *aScript) : mValid(false),
if (mFunctionName) {
JSString *str = JSD_GetScriptFunctionId(mCx, mScript);
if (str)
AssignToJSString(mFunctionName, str);
AssignToJSString(mCx, mFunctionName, str);
}
mBaseLineNumber = JSD_GetScriptBaseLineNumber(mCx, mScript);
mLineExtent = JSD_GetScriptLineExtent(mCx, mScript);
@ -1908,7 +1909,7 @@ jsdStackFrame::GetFunctionName(nsACString &_rval)
ASSERT_VALID_EPHEMERAL;
JSString *str = JSD_GetIdForStackFrame(mCx, mThreadState, mStackFrameInfo);
if (str)
return AssignToJSString(&_rval, str);
return AssignToJSString(mCx, &_rval, str);
_rval.Assign("anonymous");
return NS_OK;
@ -2238,7 +2239,7 @@ NS_IMETHODIMP
jsdValue::GetJsFunctionName(nsACString &_rval)
{
ASSERT_VALID_EPHEMERAL;
return AssignToJSString(&_rval, JSD_GetValueFunctionId(mCx, mValue));
return AssignToJSString(mCx, &_rval, JSD_GetValueFunctionId(mCx, mValue));
}
NS_IMETHODIMP

View File

@ -0,0 +1,126 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=78:
*
* 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/. */
#ifndef js_CharacterEncoding_h___
#define js_CharacterEncoding_h___
#include "mozilla/Range.h"
#include "js/Utility.h"
#include "jspubtd.h"
namespace JS {
/*
* By default, all C/C++ 1-byte-per-character strings passed into the JSAPI
* are treated as ISO/IEC 8859-1, also known as Latin-1. That is, each
* byte is treated as a 2-byte character, and there is no way to pass in a
* string containing characters beyond U+00FF.
*/
class Latin1Chars : public mozilla::Range<unsigned char>
{
typedef mozilla::Range<unsigned char> Base;
public:
Latin1Chars() : Base() {}
Latin1Chars(char *bytes, size_t length) : Base(reinterpret_cast<unsigned char *>(bytes), length) {}
};
/*
* A Latin1Chars, but with \0 termination for C compatibility.
*/
class Latin1CharsZ : public mozilla::RangedPtr<unsigned char>
{
typedef mozilla::RangedPtr<unsigned char> Base;
public:
Latin1CharsZ() : Base(NULL, 0) {}
Latin1CharsZ(char *bytes, size_t length)
: Base(reinterpret_cast<unsigned char *>(bytes), length)
{
JS_ASSERT(bytes[length] == '\0');
}
Latin1CharsZ(unsigned char *bytes, size_t length)
: Base(bytes, length)
{
JS_ASSERT(bytes[length] == '\0');
}
char *c_str() { return reinterpret_cast<char *>(get()); }
};
/*
* SpiderMonkey also deals directly with UTF-8 encoded text in some places.
*/
class UTF8CharsZ : public mozilla::RangedPtr<unsigned char>
{
typedef mozilla::RangedPtr<unsigned char> Base;
public:
UTF8CharsZ() : Base(NULL, 0) {}
UTF8CharsZ(char *bytes, size_t length)
: Base(reinterpret_cast<unsigned char *>(bytes), length)
{
JS_ASSERT(bytes[length] == '\0');
}
};
/*
* SpiderMonkey uses a 2-byte character representation: it is a
* 2-byte-at-a-time view of a UTF-16 byte stream. This is similar to UCS-2,
* but unlike UCS-2, we do not strip UTF-16 extension bytes. This allows a
* sufficiently dedicated JavaScript program to be fully unicode-aware by
* manually interpreting UTF-16 extension characters embedded in the JS
* string.
*/
class TwoByteChars : public mozilla::Range<jschar>
{
typedef mozilla::Range<jschar> Base;
public:
TwoByteChars() : Base() {}
TwoByteChars(jschar *chars, size_t length) : Base(chars, length) {}
TwoByteChars(const jschar *chars, size_t length) : Base(const_cast<jschar *>(chars), length) {}
};
/*
* A TwoByteChars, but \0 terminated for compatibility with JSFlatString.
*/
class TwoByteCharsZ : public mozilla::RangedPtr<jschar>
{
typedef mozilla::RangedPtr<jschar> Base;
public:
TwoByteCharsZ(jschar *chars, size_t length)
: Base(chars, length)
{
JS_ASSERT(chars[length] = '\0');
}
};
/*
* Convert a 2-byte character sequence to "ISO-Latin-1". This works by
* truncating each 2-byte pair in the sequence to a 1-byte pair. If the source
* contains any UTF-16 extension characters, then this may give invalid Latin1
* output. The returned string is zero terminated. The returned string or the
* returned string's |start()| must be freed with JS_free or js_free,
* respectively. If allocation fails, an OOM error will be set and the method
* will return a NULL chars (which can be tested for with the ! operator).
* This method cannot trigger GC.
*/
extern Latin1CharsZ
LossyTwoByteCharsToNewLatin1CharsZ(JSContext *cx, TwoByteChars tbchars);
} // namespace JS
inline void JS_free(JS::Latin1CharsZ &ptr) { js_free((void*)ptr.get()); }
#endif // js_CharacterEncoding_h___

View File

@ -127,6 +127,7 @@ CPPSRCS = \
String.cpp \
BytecodeCompiler.cpp \
BytecodeEmitter.cpp \
CharacterEncoding.cpp \
FoldConstants.cpp \
Intl.cpp \
NameFunctions.cpp \
@ -216,6 +217,7 @@ EXPORTS_NAMESPACES += js
# that we ensure we don't over-expose our internal integer typedefs. Note that
# LegacyIntTypes.h below is deliberately exempted from this requirement.
EXPORTS_js = \
CharacterEncoding.h \
HashTable.h \
HeapAPI.h \
LegacyIntTypes.h \

View File

@ -32,6 +32,7 @@
#include "frontend/Parser.h"
#include "frontend/TokenStream.h"
#include "js/CharacterEncoding.h"
#include "vm/Keywords.h"
#include "vm/RegExpObject.h"
#include "vm/StringBuffer.h"
@ -564,7 +565,8 @@ TokenStream::reportCompileErrorNumberVA(ParseNode *pn, unsigned flags, unsigned
err.report.uclinebuf = windowBuf.extractWellSized();
if (!err.report.uclinebuf)
return false;
err.report.linebuf = DeflateString(cx, err.report.uclinebuf, windowLength);
TwoByteChars tbchars(err.report.uclinebuf, windowLength);
err.report.linebuf = LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str();
if (!err.report.linebuf)
return false;
@ -728,7 +730,8 @@ TokenStream::getXMLEntity()
bad:
/* No match: throw a TypeError per ECMA-357 10.3.2.1 step 8(a). */
JS_ASSERT((tb.end() - bp) >= 1);
bytes = DeflateString(cx, bp + 1, (tb.end() - bp) - 1);
TwoByteChars tbchars(bp + 1, (tb.end() - bp) - 1);
bytes = LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str();
if (bytes) {
reportError(msg, bytes);
js_free(bytes);

View File

@ -68,6 +68,7 @@ CPPSRCS = \
testStringBuffer.cpp \
testTrap.cpp \
testTypedArrays.cpp \
testUTF8.cpp \
testVersion.cpp \
testXDR.cpp \
$(NULL)

View File

@ -0,0 +1,46 @@
/* -*- 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"
#include "jsapi.h"
#include "jsstr.h"
#include "js/CharacterEncoding.h"
BEGIN_TEST(testUTF8_badUTF8)
{
static const char badUTF8[] = "...\xC0...";
JSString *str = JS_NewStringCopyZ(cx, badUTF8);
CHECK(str);
const jschar *chars = JS_GetStringCharsZ(cx, str);
CHECK(chars);
CHECK(chars[3] == 0x00C0);
return true;
}
END_TEST(testUTF8_badUTF8)
BEGIN_TEST(testUTF8_bigUTF8)
{
static const char bigUTF8[] = "...\xFB\xBF\xBF\xBF\xBF...";
JSString *str = JS_NewStringCopyZ(cx, bigUTF8);
CHECK(str);
const jschar *chars = JS_GetStringCharsZ(cx, str);
CHECK(chars);
CHECK(chars[3] == 0x00FB);
return true;
}
END_TEST(testUTF8_bigUTF8)
BEGIN_TEST(testUTF8_badSurrogate)
{
static const jschar badSurrogate[] = { 'A', 'B', 'C', 0xDEEE, 'D', 'E', 0 };
JS::TwoByteChars tbchars(badSurrogate, js_strlen(badSurrogate));
JS::Latin1CharsZ latin1 = JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars);
CHECK(latin1);
CHECK(latin1[3] == 0x00EE);
return true;
}
END_TEST(testUTF8_badSurrogate)

View File

@ -64,6 +64,7 @@
#include "frontend/BytecodeCompiler.h"
#include "gc/Marking.h"
#include "gc/Memory.h"
#include "js/CharacterEncoding.h"
#include "js/MemoryMetrics.h"
#include "vm/Debugger.h"
#include "vm/NumericConversions.h"
@ -6231,27 +6232,24 @@ JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, size_
}
JS_PUBLIC_API(char *)
JS_EncodeString(JSContext *cx, JSRawString strArg)
JS_EncodeString(JSContext *cx, JSRawString str)
{
RootedString str(cx, strArg);
AutoAssertNoGC nogc;
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
const jschar *chars = str->getChars(cx);
if (!chars)
JSLinearString *linear = str->ensureLinear(cx);
if (!linear)
return NULL;
return DeflateString(cx, chars, str->length());
return LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->range()).c_str();
}
JS_PUBLIC_API(size_t)
JS_GetStringEncodingLength(JSContext *cx, JSString *str)
{
/* jsd calls us with a NULL cx. Ugh. */
if (cx) {
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
}
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
const jschar *chars = str->getChars(cx);
if (!chars)
@ -6260,8 +6258,11 @@ JS_GetStringEncodingLength(JSContext *cx, JSString *str)
}
JS_PUBLIC_API(size_t)
JS_EncodeStringToBuffer(JSString *str, char *buffer, size_t length)
JS_EncodeStringToBuffer(JSContext *cx, JSString *str, char *buffer, size_t length)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
/*
* FIXME bug 612141 - fix DeflateStringToBuffer interface so the result
* would allow to distinguish between insufficient buffer and encoding

View File

@ -5554,7 +5554,7 @@ JS_GetStringEncodingLength(JSContext *cx, JSString *str);
* written into the buffer.
*/
JS_PUBLIC_API(size_t)
JS_EncodeStringToBuffer(JSString *str, char *buffer, size_t length);
JS_EncodeStringToBuffer(JSContext *cx, JSString *str, char *buffer, size_t length);
class JSAutoByteString
{

View File

@ -23,6 +23,8 @@
# include <string>
#endif // ANDROID
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsutil.h"
#include "jsclist.h"
@ -55,6 +57,7 @@
# include "methodjit/MethodJIT.h"
#endif
#include "gc/Marking.h"
#include "js/CharacterEncoding.h"
#include "js/MemoryMetrics.h"
#include "frontend/TokenStream.h"
#include "frontend/ParseMaps.h"
@ -69,6 +72,7 @@ using namespace js;
using namespace js::gc;
using mozilla::DebugOnly;
using mozilla::PointerRangeSize;
bool
js::AutoCycleDetector::init()
@ -832,8 +836,10 @@ js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
JS_ASSERT(expandedArgs == argCount);
*out = 0;
js_free(buffer);
*messagep = DeflateString(cx, reportp->ucmessage,
size_t(out - reportp->ucmessage));
TwoByteChars ucmsg(reportp->ucmessage,
PointerRangeSize(static_cast<const jschar *>(reportp->ucmessage),
static_cast<const jschar *>(out)));
*messagep = LossyTwoByteCharsToNewLatin1CharsZ(cx, ucmsg).c_str();
if (!*messagep)
goto error;
}

View File

@ -291,13 +291,13 @@ MakeTypeId(JSContext *cx, jsid id)
*/
if (JSID_IS_STRING(id)) {
JSFlatString *str = JSID_TO_FLAT_STRING(id);
const jschar *cp = str->getCharsZ(cx);
if (JS7_ISDEC(*cp) || *cp == '-') {
cp++;
while (JS7_ISDEC(*cp))
cp++;
if (*cp == 0)
return JSID_VOID;
TwoByteChars cp = str->range();
if (JS7_ISDEC(cp[0]) || cp[0] == '-') {
for (size_t i = 1; i < cp.length(); ++i) {
if (!JS7_ISDEC(cp[i]))
return id;
}
return JSID_VOID;
}
return id;
}

View File

@ -38,9 +38,9 @@
#include "jsstr.h"
#include "ds/Sort.h"
#include "frontend/BytecodeEmitter.h"
#include "frontend/TokenStream.h"
#include "js/CharacterEncoding.h"
#include "vm/Debugger.h"
#include "vm/StringBuffer.h"
@ -6262,10 +6262,11 @@ js::DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v,
return NULL;
}
Rooted<JSStableString *> stable(cx, fallback->ensureStable(cx));
if (!stable)
Rooted<JSLinearString *> linear(cx, fallback->ensureLinear(cx));
if (!linear)
return NULL;
return DeflateString(cx, stable->chars().get(), stable->length());
TwoByteChars tbchars(linear->chars(), linear->length());
return LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str();
}
static bool
@ -6352,10 +6353,10 @@ js::DecompileArgument(JSContext *cx, int formalIndex, HandleValue v)
if (!fallback)
return NULL;
Rooted<JSStableString *> stable(cx, fallback->ensureStable(cx));
if (!stable)
Rooted<JSLinearString *> linear(cx, fallback->ensureLinear(cx));
if (!linear)
return NULL;
return DeflateString(cx, stable->chars().get(), stable->length());
return LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->range()).c_str();
}
static char *

View File

@ -17,6 +17,8 @@
#include "jspubtd.h"
#include "jsstr.h"
#include "js/CharacterEncoding.h"
using namespace js;
/*
@ -360,8 +362,8 @@ 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)
static int
cvt_ws(SprintfState *ss, const jschar *ws, int width, int prec, int flags)
{
int result;
/*
@ -369,12 +371,15 @@ static int cvt_ws(SprintfState *ss, const jschar *ws, int width, int prec,
* and malloc() is used to allocate the buffer buffer.
*/
if (ws) {
int slen = js_strlen(ws);
char *s = DeflateString(NULL, ws, slen);
if (!s)
size_t wslen = js_strlen(ws);
char *latin1 = js_pod_malloc<char>(wslen + 1);
if (!latin1)
return -1; /* JSStuffFunc error indicator. */
result = cvt_s(ss, s, width, prec, flags);
js_free(s);
for (size_t i = 0; i < wslen; ++i)
latin1[i] = (char)ws[i];
latin1[wslen] = '\0';
result = cvt_s(ss, latin1, width, prec, flags);
js_free(latin1);
} else {
result = cvt_s(ss, NULL, width, prec, flags);
}

View File

@ -27,6 +27,7 @@
#include "frontend/Parser.h"
#include "frontend/TokenStream.h"
#include "js/CharacterEncoding.h"
#include "vm/RegExpObject.h"
#include "jsscriptinlines.h"
@ -3442,7 +3443,8 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp)
if (!chars)
return JS_FALSE;
filename = DeflateString(cx, chars, length);
TwoByteChars tbchars(chars, length);
filename = LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str();
if (!filename)
return JS_FALSE;
}

View File

@ -3726,25 +3726,6 @@ js::InflateUTF8String(JSContext *cx, const char *bytes, size_t *lengthp)
return NULL;
}
/*
* May be called with null cx.
*/
char *
js::DeflateString(JSContext *maybecx, const jschar *chars, size_t nchars)
{
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;
}
size_t
js::GetDeflatedStringLength(JSContext *cx, const jschar *chars, size_t nchars)
{

View File

@ -224,9 +224,6 @@ InflateString(JSContext *cx, const char *bytes, size_t *length);
extern jschar *
InflateUTF8String(JSContext *cx, const char *bytes, size_t *length);
extern char *
DeflateString(JSContext *cx, const jschar *chars, size_t length);
/*
* Inflate bytes to JS chars in an existing buffer. 'chars' must be large
* enough for 'length' jschars. The buffer is NOT null-terminated.

View File

@ -20,6 +20,8 @@
#include "jsinterpinlines.h"
#include "jsautooplen.h"
#include "js/CharacterEncoding.h"
#include "vm/ScopeObject-inl.h"
#include "vm/StringObject-inl.h"
@ -2409,12 +2411,12 @@ GetElementIC::attachGetProp(VMFrame &f, HandleObject obj, HandleValue v, HandleP
CodeLocationLabel cs = buffer.finalize(f);
#if DEBUG
char *chars = DeflateString(cx, v.toString()->getChars(cx), v.toString()->length());
Latin1CharsZ latin1 = LossyTwoByteCharsToNewLatin1CharsZ(cx, v.toString()->ensureLinear(cx)->range());
JaegerSpew(JSpew_PICs, "generated %s stub at %p for atom %p (\"%s\") shape %p (%s: %d)\n",
js_CodeName[JSOp(*f.pc())], cs.executableAddress(), (void*)name, chars,
js_CodeName[JSOp(*f.pc())], cs.executableAddress(), (void*)name, latin1.get(),
(void*)holder->lastProperty(), cx->fp()->script()->filename,
CurrentLine(cx));
js_free(chars);
JS_free(latin1);
#endif
// Update the inline guards, if needed.

View File

@ -2440,47 +2440,6 @@ ToInt32(JSContext *cx, unsigned argc, jsval *vp)
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 };
static JSBool
TestUTF8(JSContext *cx, unsigned argc, jsval *vp)
{
int32_t mode = 1;
jschar chars[20];
size_t charsLength = 5;
char bytes[20];
size_t bytesLength = 20;
if (argc && !JS_ValueToInt32(cx, *JS_ARGV(cx, vp), &mode))
return false;
/* The following throw errors if compiled with UTF-8. */
switch (mode) {
/* mode 1: malformed UTF-8 string. */
case 1:
JS_NewStringCopyZ(cx, badUTF8);
break;
/* mode 2: big UTF-8 character. */
case 2:
JS_NewStringCopyZ(cx, bigUTF8);
break;
/* mode 3: bad surrogate character. */
case 3:
DeflateStringToBuffer(cx, badSurrogate, 6, bytes, &bytesLength);
break;
/* mode 4: use a too small buffer. */
case 4:
JS_DecodeBytes(cx, "1234567890", 10, chars, &charsLength);
break;
default:
JS_ReportError(cx, "invalid mode parameter");
return false;
}
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return !JS_IsExceptionPending (cx);
}
static JSBool
ThrowError(JSContext *cx, unsigned argc, jsval *vp)
{
@ -3740,10 +3699,6 @@ static JSFunctionSpecWithHelp shell_functions[] = {
"pc2line(fun[, pc])",
" Map PC to line number."),
JS_FN_HELP("testUTF8", TestUTF8, 1, 0,
"testUTF8(mode)",
" Perform UTF-8 tests (modes are 1 to 4)."),
JS_FN_HELP("throwError", ThrowError, 0, 0,
"throwError()",
" Throw an error from JS_ReportError."),

View File

@ -1,122 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
//-----------------------------------------------------------------------------
var BUGNUMBER = 232182;
var summary = 'Display non-ascii characters in JS exceptions';
var actual = '';
var expect = 'no error';
printBugNumber(BUGNUMBER);
printStatus (summary);
/*
* This test accesses an undefined Unicode symbol. If the code has not been
* compiled with JS_C_STRINGS_ARE_UTF8, the thrown error truncates Unicode
* characters to bytes. Accessing \u0440\u0441, therefore, results in a
* message talking about an undefined variable 'AB' (\x41\x42).
*/
var utf8Enabled = false;
try
{
\u0441\u0442;
}
catch (e)
{
utf8Enabled = (e.message.charAt (0) == '\u0441');
}
// Run the tests only if UTF-8 is enabled
printStatus('UTF-8 is ' + (utf8Enabled?'':'not ') + 'enabled');
if (!utf8Enabled)
{
reportCompare('Not run', 'Not run', 'utf8 is not enabled');
}
else
{
status = summary + ': Throw Error with Unicode message';
expect = 'test \u0440\u0441';
try
{
throw Error (expect);
}
catch (e)
{
actual = e.message;
}
reportCompare(expect, actual, status);
var inShell = (typeof stringsAreUTF8 == "function");
if (!inShell)
{
inShell = (typeof stringsAreUtf8 == "function");
if (inShell)
{
this.stringsAreUTF8 = stringsAreUtf8;
this.testUTF8 = testUtf8;
}
}
if (inShell && stringsAreUTF8())
{
status = summary + ': UTF-8 test: bad UTF-08 sequence';
expect = 'Error';
actual = 'No error!';
try
{
testUTF8(1);
}
catch (e)
{
actual = 'Error';
}
reportCompare(expect, actual, status);
status = summary + ': UTF-8 character too big to fit into Unicode surrogate pairs';
expect = 'Error';
actual = 'No error!';
try
{
testUTF8(2);
}
catch (e)
{
actual = 'Error';
}
reportCompare(expect, actual, status);
status = summary + ': bad Unicode surrogate character';
expect = 'Error';
actual = 'No error!';
try
{
testUTF8(3);
}
catch (e)
{
actual = 'Error';
}
reportCompare(expect, actual, status);
}
if (inShell)
{
status = summary + ': conversion target buffer overrun';
expect = 'Error';
actual = 'No error!';
try
{
testUTF8(4);
}
catch (e)
{
actual = 'Error';
}
reportCompare(expect, actual, status);
}
}

View File

@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=78:
*
* 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 "jscntxt.h"
#include "js/CharacterEncoding.h"
using namespace JS;
Latin1CharsZ
JS::LossyTwoByteCharsToNewLatin1CharsZ(JSContext *cx, TwoByteChars tbchars)
{
AutoAssertNoGC nogc;
JS_ASSERT(cx);
size_t len = tbchars.length();
unsigned char *latin1 = cx->pod_malloc<unsigned char>(len + 1);
if (!latin1)
return Latin1CharsZ();
for (size_t i = 0; i < len; ++i)
latin1[i] = static_cast<unsigned char>(tbchars[i]);
latin1[len] = '\0';
return Latin1CharsZ(latin1, len);
}

View File

@ -11,6 +11,8 @@
#include "mozilla/Attributes.h"
#include "mozilla/GuardObjects.h"
#include "js/CharacterEncoding.h"
#include "jsapi.h"
#include "jsatom.h"
#include "jsfriendapi.h"
@ -477,6 +479,11 @@ class JSLinearString : public JSString
JS_ASSERT(JSString::isLinear());
return d.u1.chars;
}
JS::TwoByteChars range() const {
JS_ASSERT(JSString::isLinear());
return JS::TwoByteChars(d.u1.chars, length());
}
};
JS_STATIC_ASSERT(sizeof(JSLinearString) == sizeof(JSString));

View File

@ -575,7 +575,7 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
if (!buffer) {
return false;
}
JS_EncodeStringToBuffer(str, buffer, length);
JS_EncodeStringToBuffer(cx, str, buffer, length);
buffer[length] = '\0';
*((void**)d) = buffer;
return true;
@ -701,7 +701,7 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
if (rs->Length() != uint32_t(length)) {
return false;
}
JS_EncodeStringToBuffer(str, rs->BeginWriting(), length);
JS_EncodeStringToBuffer(cx, str, rs->BeginWriting(), length);
return true;
}
@ -1875,7 +1875,7 @@ XPCConvert::JSStringWithSize2Native(XPCCallContext& ccx, void* d, jsval s,
if (!buffer) {
return false;
}
JS_EncodeStringToBuffer(str, buffer, len);
JS_EncodeStringToBuffer(cx, str, buffer, len);
buffer[len] = '\0';
*((char**)d) = buffer;

View File

@ -122,7 +122,7 @@ XPCJSStackFrame::CreateStack(JSContext* cx, XPCJSStackFrame** stack)
if (length != size_t(-1)) {
self->mFunname = static_cast<char *>(nsMemory::Alloc(length + 1));
if (self->mFunname) {
JS_EncodeStringToBuffer(funid, self->mFunname, length);
JS_EncodeStringToBuffer(cx, funid, self->mFunname, length);
self->mFunname[length] = '\0';
}
}