Bug 609440, part 3 - remove fallible public APIs, update mozilla (r=bent,jst,mrbkap,waldo,sdwilsh)

This commit is contained in:
Luke Wagner 2010-12-03 00:24:17 -08:00
parent b53039418b
commit 56b2810a26
67 changed files with 898 additions and 531 deletions

View File

@ -114,7 +114,7 @@ static inline const PRUnichar *
IDToString(JSContext *cx, jsid id)
{
if (JSID_IS_STRING(id))
return reinterpret_cast<PRUnichar*>(JS_GetStringChars(JSID_TO_STRING(id)));
return JS_GetInternedStringChars(JSID_TO_STRING(id));
JSAutoRequest ar(cx);
jsval idval;
@ -123,7 +123,7 @@ IDToString(JSContext *cx, jsid id)
JSString *str = JS_ValueToString(cx, idval);
if(!str)
return nsnull;
return reinterpret_cast<PRUnichar*>(JS_GetStringChars(str));
return JS_GetStringCharsZ(cx, str);
}
class nsAutoInPrincipalDomainOriginSetter {

View File

@ -95,9 +95,10 @@ static void
getUTF8StringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum,
uintN argc, jsval *argv, nsCString& aRetval)
{
aRetval.Truncate();
if (argc <= argNum || !JSVAL_IS_STRING(argv[argNum])) {
JS_ReportError(cx, "String argument expected");
aRetval.Truncate();
return;
}
@ -106,12 +107,13 @@ getUTF8StringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum,
* to have an object to represent a target in subsequent versions.
*/
JSString *str = JSVAL_TO_STRING(argv[argNum]);
if (!str) {
aRetval.Truncate();
if (!str)
return;
const PRUnichar *data = JS_GetStringCharsZ(cx, str);
if (!data)
return;
}
PRUnichar *data = (PRUnichar*)JS_GetStringChars(str);
CopyUTF16toUTF8(data, aRetval);
}

View File

@ -208,7 +208,11 @@ nsFrameMessageManager::GetParamsForMessage(nsAString& aMessageName,
JSAutoRequest ar(ctx);
JSString* str;
if (argc && (str = JS_ValueToString(ctx, argv[0])) && str) {
aMessageName.Assign(nsDependentJSString(str));
nsDependentJSString depStr;
if (!depStr.init(ctx, str)) {
return NS_ERROR_OUT_OF_MEMORY;
}
aMessageName.Assign(depStr);
}
if (argc >= 2) {

View File

@ -2940,17 +2940,27 @@ nsWebSocket::Initialize(nsISupports* aOwner,
if (!jsstr) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
urlParam.Assign(reinterpret_cast<const PRUnichar*>(JS_GetStringChars(jsstr)),
JS_GetStringLength(jsstr));
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(aContext, jsstr, &length);
if (!chars) {
return NS_ERROR_OUT_OF_MEMORY;
}
urlParam.Assign(chars, length);
if (aArgc == 2) {
jsstr = JS_ValueToString(aContext, aArgv[1]);
if (!jsstr) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
protocolParam.
Assign(reinterpret_cast<const PRUnichar*>(JS_GetStringChars(jsstr)),
JS_GetStringLength(jsstr));
chars = JS_GetStringCharsAndLength(aContext, jsstr, &length);
if (!chars) {
return NS_ERROR_OUT_OF_MEMORY;
}
protocolParam.Assign(chars, length);
if (protocolParam.IsEmpty()) {
return NS_ERROR_DOM_SYNTAX_ERR;
}

View File

@ -140,7 +140,10 @@ nsEventListenerInfo::ToSource(nsAString& aResult)
if (GetJSVal(&v)) {
JSString* str = JS_ValueToSource(cx, v);
if (str) {
aResult.Assign(nsDependentJSString(str));
nsDependentJSString depStr;
if (depStr.init(cx, str)) {
aResult.Assign(depStr);
}
}
}
}

View File

@ -140,7 +140,10 @@ nsHTMLAudioElement::Initialize(nsISupports* aOwner, JSContext* aContext,
if (!jsstr)
return NS_ERROR_FAILURE;
nsDependentJSString str(jsstr);
nsDependentJSString str;
if (!str.init(aContext, jsstr))
return NS_ERROR_FAILURE;
rv = SetAttr(kNameSpaceID_None, nsGkAtoms::src, str, PR_TRUE);
if (NS_FAILED(rv))
return rv;

View File

@ -46,6 +46,7 @@
#include "nsIScriptSecurityManager.h"
#include "nsIXPConnect.h"
#include "jsapi.h"
#include "nsJSUtils.h"
#include "nsFrameManager.h"
#include "nsDisplayList.h"
@ -502,8 +503,11 @@ nsHTMLCanvasElement::GetContext(const nsAString& aContextId,
}
JSString *propnameString = JS_ValueToString(cx, propname);
nsDependentString pstr(JS_GetStringChars(propnameString), JS_GetStringLength(propnameString));
nsDependentJSString pstr;
if (!propnameString || !pstr.init(cx, propnameString)) {
mCurrentContext = nsnull;
return NS_ERROR_FAILURE;
}
if (JSVAL_IS_BOOLEAN(propval)) {
newProps->SetPropertyAsBool(pstr, propval == JSVAL_TRUE ? PR_TRUE : PR_FALSE);
@ -512,8 +516,14 @@ nsHTMLCanvasElement::GetContext(const nsAString& aContextId,
} else if (JSVAL_IS_DOUBLE(propval)) {
newProps->SetPropertyAsDouble(pstr, JSVAL_TO_DOUBLE(propval));
} else if (JSVAL_IS_STRING(propval)) {
newProps->SetPropertyAsAString(pstr, nsDependentString(JS_GetStringChars(JS_ValueToString(cx, propval)),
JS_GetStringLength(JS_ValueToString(cx, propval))));
JSString *propvalString = JS_ValueToString(cx, propval);
nsDependentJSString vstr;
if (!propvalString || !vstr.init(cx, propvalString)) {
mCurrentContext = nsnull;
return NS_ERROR_FAILURE;
}
newProps->SetPropertyAsAString(pstr, vstr);
}
}
}

View File

@ -412,10 +412,13 @@ nsHTMLOptionElement::Initialize(nsISupports* aOwner,
return result;
}
textContent->SetText(reinterpret_cast<const PRUnichar*>
(JS_GetStringChars(jsstr)),
JS_GetStringLength(jsstr),
PR_FALSE);
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(aContext, jsstr, &length);
if (!chars) {
return NS_ERROR_FAILURE;
}
textContent->SetText(chars, length, PR_FALSE);
result = AppendChildTo(textContent, PR_FALSE);
if (NS_FAILED(result)) {
@ -429,9 +432,14 @@ nsHTMLOptionElement::Initialize(nsISupports* aOwner,
return NS_ERROR_FAILURE;
}
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(aContext, jsstr, &length);
if (!chars) {
return NS_ERROR_FAILURE;
}
// Set the value attribute for this element
nsAutoString value(reinterpret_cast<const PRUnichar*>
(JS_GetStringChars(jsstr)));
nsAutoString value(chars, length);
result = SetAttr(kNameSpaceID_None, nsGkAtoms::value, value,
PR_FALSE);

View File

@ -89,6 +89,11 @@ CPPSRCS += txMozillaStylesheetCompiler.cpp \
txMozillaXSLTProcessor.cpp
endif
# For nsDependentJSString
LOCAL_INCLUDES += \
-I$(topsrcdir)/dom/base \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a
# static lib.
FORCE_STATIC_LIB = 1

View File

@ -67,6 +67,7 @@
#include "txExprParser.h"
#include "nsIErrorService.h"
#include "nsIScriptSecurityManager.h"
#include "nsJSUtils.h"
using namespace mozilla::dom;
@ -1465,10 +1466,8 @@ txVariable::Convert(nsIVariant *aValue, txAExprResult** aResult)
JSString *str = JS_ValueToString(cx, OBJECT_TO_JSVAL(jsobj));
NS_ENSURE_TRUE(str, NS_ERROR_FAILURE);
const PRUnichar *strChars =
reinterpret_cast<const PRUnichar*>
(::JS_GetStringChars(str));
nsDependentString value(strChars, ::JS_GetStringLength(str));
nsDependentJSString value;
NS_ENSURE_TRUE(value.init(cx, str), NS_ERROR_FAILURE);
*aResult = new StringResult(value, nsnull);
if (!*aResult) {

View File

@ -5064,7 +5064,6 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
}
JSObject *proto = ::JS_GetPrototype(cx, obj);
JSString *jsstr = JSID_TO_STRING(id);
JSBool hasProp;
if (!proto || !::JS_HasPropertyById(cx, proto, id, &hasProp) ||
@ -5075,7 +5074,7 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
return JS_TRUE;
}
nsDependentJSString str(jsstr);
nsDependentJSString str(id);
nsCOMPtr<nsISupports> result;
nsWrapperCache *cache;
{
@ -5414,7 +5413,10 @@ nsWindowSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
vp, getter_AddRefs(holder));
NS_ENSURE_SUCCESS(rv, rv);
rv = location->SetHref(nsDependentJSString(val));
nsDependentJSString depStr;
NS_ENSURE_TRUE(depStr.init(cx, val), NS_ERROR_UNEXPECTED);
rv = location->SetHref(depStr);
return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
}
@ -6269,14 +6271,14 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
// static
nsresult
nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
JSObject *obj, JSString *str, PRBool *did_resolve)
JSObject *obj, jsid id, PRBool *did_resolve)
{
*did_resolve = PR_FALSE;
nsScriptNameSpaceManager *nameSpaceManager = nsJSRuntime::GetNameSpaceManager();
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsDependentJSString name(str);
nsDependentJSString name(id);
const nsGlobalNameStruct *name_struct = nsnull;
const PRUnichar *class_name = nsnull;
@ -6486,10 +6488,8 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
NS_ENSURE_SUCCESS(rv, rv);
JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str),
prop_val, nsnull, nsnull,
JSPROP_ENUMERATE);
JSBool ok = ::JS_DefinePropertyById(cx, obj, id, prop_val, nsnull, nsnull,
JSPROP_ENUMERATE);
*did_resolve = PR_TRUE;
@ -6648,8 +6648,6 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// method on an interface that would let us just call into the
// window code directly...
JSString *str = JSID_TO_STRING(id);
if (!xpc::WrapperFactory::IsXrayWrapper(obj) ||
xpc::WrapperFactory::IsPartiallyTransparent(obj)) {
nsCOMPtr<nsIDocShellTreeNode> dsn(do_QueryInterface(win->GetDocShell()));
@ -6663,7 +6661,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
if (count > 0) {
nsCOMPtr<nsIDocShellTreeItem> child;
const jschar *chars = ::JS_GetStringChars(str);
const jschar *chars = ::JS_GetInternedStringChars(JSID_TO_STRING(id));
dsn->FindChildWithName(reinterpret_cast<const PRUnichar*>(chars),
PR_FALSE, PR_TRUE, nsnull, nsnull,
@ -6712,7 +6710,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// which have been registered with the script namespace manager.
JSBool did_resolve = JS_FALSE;
rv = GlobalResolve(win, cx, obj, str, &did_resolve);
rv = GlobalResolve(win, cx, obj, id, &did_resolve);
NS_ENSURE_SUCCESS(rv, rv);
if (did_resolve) {
@ -8382,7 +8380,10 @@ nsDocumentSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSString *val = ::JS_ValueToString(cx, *vp);
NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED);
rv = location->SetHref(nsDependentJSString(val));
nsDependentJSString depStr;
NS_ENSURE_TRUE(depStr.init(cx, val), NS_ERROR_UNEXPECTED);
rv = location->SetHref(depStr);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
@ -8471,7 +8472,10 @@ ResolveImpl(JSContext *cx, nsIXPConnectWrappedNative *wrapper, jsid id,
JSString *str = IdToString(cx, id);
NS_ENSURE_TRUE(str, NS_ERROR_UNEXPECTED);
return doc->ResolveName(nsDependentJSString(str), nsnull, result, aCache);
nsDependentJSString depStr;
NS_ENSURE_TRUE(depStr.init(cx, str), NS_ERROR_UNEXPECTED);
return doc->ResolveName(depStr, nsnull, result, aCache);
}
// static
@ -8509,8 +8513,13 @@ nsHTMLDocumentSH::DocumentOpen(JSContext *cx, uintN argc, jsval *vp)
nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_OUT_OF_MEMORY);
return JS_FALSE;
}
nsDependentJSString depStr;
if (!depStr.init(cx, jsstr)) {
nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_OUT_OF_MEMORY);
return JS_FALSE;
}
nsAutoString type;
type.Assign(nsDependentJSString(jsstr));
type.Assign(depStr);
ToLowerCase(type);
nsCAutoString actualType, dummy;
NS_ParseContentType(NS_ConvertUTF16toUTF8(type), actualType, dummy);
@ -8528,9 +8537,13 @@ nsHTMLDocumentSH::DocumentOpen(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
}
replace = NS_LITERAL_STRING("replace").
Equals(reinterpret_cast<const PRUnichar*>
(::JS_GetStringChars(jsstr)));
const jschar *chars = ::JS_GetStringCharsZ(cx, jsstr);
if (!chars) {
nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_OUT_OF_MEMORY);
return JS_FALSE;
}
replace = NS_LITERAL_STRING("replace").Equals(chars);
}
nsCOMPtr<nsIDOMDocument> retval;
@ -8849,8 +8862,13 @@ nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, uintN argc, jsval *vp)
self = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
}
return ::JS_GetUCProperty(cx, self, ::JS_GetStringChars(str),
::JS_GetStringLength(str), vp);
size_t length;
const jschar *chars = ::JS_GetStringCharsAndLength(cx, str, &length);
if (!chars) {
return JS_FALSE;
}
return ::JS_GetUCProperty(cx, self, chars, length, vp);
}
@ -8970,8 +8988,6 @@ nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj,
if (JSID_IS_STRING(id)) {
nsDocument *doc = GetDocument(cx, obj);
JSString *str = JSID_TO_STRING(id);
JSObject *proto = ::JS_GetPrototype(cx, obj);
if (NS_UNLIKELY(!proto)) {
return JS_TRUE;
@ -8987,7 +9003,7 @@ nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj,
}
nsRefPtr<nsContentList> tags =
doc->GetElementsByTagName(nsDependentJSString(str));
doc->GetElementsByTagName(nsDependentJSString(id));
if (tags) {
jsval v;
@ -9159,11 +9175,11 @@ nsHTMLDocumentSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
// static
nsresult
nsHTMLFormElementSH::FindNamedItem(nsIForm *aForm, JSString *str,
nsHTMLFormElementSH::FindNamedItem(nsIForm *aForm, jsid id,
nsISupports **aResult,
nsWrapperCache **aCache)
{
nsDependentJSString name(str);
nsDependentJSString name(id);
*aResult = aForm->ResolveName(name).get();
// FIXME Get the wrapper cache from nsIForm::ResolveName
@ -9197,8 +9213,7 @@ nsHTMLFormElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
nsCOMPtr<nsISupports> result;
nsWrapperCache *cache;
JSString *str = JSID_TO_STRING(id);
FindNamedItem(form, str, getter_AddRefs(result), &cache);
FindNamedItem(form, id, getter_AddRefs(result), &cache);
if (result) {
JSAutoRequest ar(cx);
@ -9228,8 +9243,7 @@ nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
nsCOMPtr<nsISupports> result;
nsWrapperCache *cache;
JSString *str = JSID_TO_STRING(id);
FindNamedItem(form, str, getter_AddRefs(result), &cache);
FindNamedItem(form, id, getter_AddRefs(result), &cache);
if (result) {
// Wrap result, result can be either an element or a list of
@ -10173,11 +10187,14 @@ nsStorageSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
if (!jsstr)
return JS_FALSE;
nsDependentJSString depStr;
if (!depStr.init(cx, jsstr))
return JS_FALSE;
// GetItem() will return null if the caller can't access the session
// storage item.
nsCOMPtr<nsIDOMStorageItem> item;
nsresult rv = storage->GetItem(nsDependentJSString(jsstr),
getter_AddRefs(item));
nsresult rv = storage->GetItem(depStr, getter_AddRefs(item));
NS_ENSURE_SUCCESS(rv, rv);
if (item) {
@ -10212,11 +10229,16 @@ nsStorageSH::SetProperty(nsIXPConnectWrappedNative *wrapper,
JSString *key = IdToString(cx, id);
NS_ENSURE_TRUE(key, NS_ERROR_UNEXPECTED);
nsDependentJSString keyStr;
NS_ENSURE_TRUE(keyStr.init(cx, key), NS_ERROR_UNEXPECTED);
JSString *value = ::JS_ValueToString(cx, *vp);
NS_ENSURE_TRUE(value, NS_ERROR_UNEXPECTED);
nsresult rv = storage->SetItem(nsDependentJSString(key),
nsDependentJSString(value));
nsDependentJSString valueStr;
NS_ENSURE_TRUE(valueStr.init(cx, value), NS_ERROR_UNEXPECTED);
nsresult rv = storage->SetItem(keyStr, valueStr);
if (NS_SUCCEEDED(rv)) {
rv = NS_SUCCESS_I_DID_SOMETHING;
}
@ -10235,7 +10257,10 @@ nsStorageSH::DelProperty(nsIXPConnectWrappedNative *wrapper,
JSString *key = IdToString(cx, id);
NS_ENSURE_TRUE(key, NS_ERROR_UNEXPECTED);
nsresult rv = storage->RemoveItem(nsDependentJSString(key));
nsDependentJSString keyStr;
NS_ENSURE_TRUE(keyStr.init(cx, key), NS_ERROR_UNEXPECTED);
nsresult rv = storage->RemoveItem(keyStr);
if (NS_SUCCEEDED(rv)) {
rv = NS_SUCCESS_I_DID_SOMETHING;
}
@ -10334,10 +10359,13 @@ nsStorage2SH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
nsCOMPtr<nsIDOMStorage> storage(do_QueryWrappedNative(wrapper));
nsDependentJSString depStr;
NS_ENSURE_TRUE(depStr.init(cx, jsstr), NS_ERROR_UNEXPECTED);
// GetItem() will return null if the caller can't access the session
// storage item.
nsAutoString data;
nsresult rv = storage->GetItem(nsDependentJSString(jsstr), data);
nsresult rv = storage->GetItem(depStr, data);
NS_ENSURE_SUCCESS(rv, rv);
if (!DOMStringIsNull(data)) {
@ -10406,11 +10434,16 @@ nsStorage2SH::SetProperty(nsIXPConnectWrappedNative *wrapper,
JSString *key = IdToString(cx, id);
NS_ENSURE_TRUE(key, NS_ERROR_UNEXPECTED);
nsDependentJSString keyStr;
NS_ENSURE_TRUE(keyStr.init(cx, key), NS_ERROR_UNEXPECTED);
JSString *value = ::JS_ValueToString(cx, *vp);
NS_ENSURE_TRUE(value, NS_ERROR_UNEXPECTED);
nsresult rv = storage->SetItem(nsDependentJSString(key),
nsDependentJSString(value));
nsDependentJSString valueStr;
NS_ENSURE_TRUE(valueStr.init(cx, value), NS_ERROR_UNEXPECTED);
nsresult rv = storage->SetItem(keyStr, valueStr);
if (NS_SUCCEEDED(rv)) {
rv = NS_SUCCESS_I_DID_SOMETHING;
}
@ -10429,7 +10462,10 @@ nsStorage2SH::DelProperty(nsIXPConnectWrappedNative *wrapper,
JSString *key = IdToString(cx, id);
NS_ENSURE_TRUE(key, NS_ERROR_UNEXPECTED);
nsresult rv = storage->RemoveItem(nsDependentJSString(key));
nsDependentJSString keyStr;
NS_ENSURE_TRUE(keyStr.init(cx, key), NS_ERROR_UNEXPECTED);
nsresult rv = storage->RemoveItem(keyStr);
if (NS_SUCCEEDED(rv)) {
rv = NS_SUCCESS_I_DID_SOMETHING;
}

View File

@ -454,7 +454,7 @@ protected:
{
NS_ASSERTION(JSID_IS_STRING(id), "Don't pass non-string jsid's here!");
jschar *str = ::JS_GetStringChars(JSID_TO_STRING(id));
const jschar *str = ::JS_GetInternedStringChars(JSID_TO_STRING(id));
if (str[0] == 'o' && str[1] == 'n') {
return ReallyIsEventName(id, str[2]);
@ -519,8 +519,7 @@ protected:
}
static nsresult GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
JSObject *obj, JSString *str,
PRBool *did_resolve);
JSObject *obj, jsid id, PRBool *did_resolve);
public:
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
@ -1037,7 +1036,7 @@ protected:
{
}
static nsresult FindNamedItem(nsIForm *aForm, JSString *str,
static nsresult FindNamedItem(nsIForm *aForm, jsid id,
nsISupports **aResult, nsWrapperCache **aCache);
public:

View File

@ -724,8 +724,13 @@ static JSBool
ChangeCase(JSContext *cx, JSString *src, jsval *rval,
void(* changeCaseFnc)(const nsAString&, nsAString&))
{
nsDependentJSString depStr;
if (!depStr.init(cx, src)) {
return JS_FALSE;
}
nsAutoString result;
changeCaseFnc(nsDependentJSString(src), result);
changeCaseFnc(depStr, result);
JSString *ucstr = JS_NewUCStringCopyN(cx, (jschar*)result.get(), result.Length());
if (!ucstr) {
@ -779,11 +784,14 @@ LocaleCompare(JSContext *cx, JSString *src1, JSString *src2, jsval *rval)
}
}
nsDependentJSString depStr1, depStr2;
if (!depStr1.init(cx, src1) || !depStr2.init(cx, src2)) {
return JS_FALSE;
}
PRInt32 result;
rv = gCollation->CompareString(nsICollation::kCollationStrengthDefault,
nsDependentJSString(src1),
nsDependentJSString(src2),
&result);
depStr1, depStr2, &result);
if (NS_FAILED(rv)) {
nsDOMClassInfo::ThrowJSException(cx, rv);
@ -1591,27 +1599,36 @@ JSValueToAString(JSContext *cx, jsval val, nsAString *result,
}
JSString* jsstring = ::JS_ValueToString(cx, val);
if (jsstring) {
result->Assign(reinterpret_cast<const PRUnichar*>
(::JS_GetStringChars(jsstring)),
::JS_GetStringLength(jsstring));
} else {
result->Truncate();
if (!jsstring) {
goto error;
}
// We failed to convert val to a string. We're either OOM, or the
// security manager denied access to .toString(), or somesuch, on
// an object. Treat this case as if the result were undefined.
size_t length;
const jschar *chars;
chars = ::JS_GetStringCharsAndLength(cx, jsstring, &length);
if (!chars) {
goto error;
}
if (isUndefined) {
*isUndefined = PR_TRUE;
}
result->Assign(chars, length);
return NS_OK;
if (!::JS_IsExceptionPending(cx)) {
// JS_ValueToString() returned null w/o an exception
// pending. That means we're OOM.
error:
// We failed to convert val to a string. We're either OOM, or the
// security manager denied access to .toString(), or somesuch, on
// an object. Treat this case as if the result were undefined.
return NS_ERROR_OUT_OF_MEMORY;
}
result->Truncate();
if (isUndefined) {
*isUndefined = PR_TRUE;
}
if (!::JS_IsExceptionPending(cx)) {
// JS_ValueToString()/JS_GetStringCharsAndLength returned null w/o an
// exception pending. That means we're OOM.
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;

View File

@ -109,7 +109,7 @@ private:
nsCOMPtr<nsIArray> mArgv;
// The JS expression to evaluate or function to call, if !mExpr
JSString *mExpr;
JSFlatString *mExpr;
JSObject *mFunObj;
};
@ -134,10 +134,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
else if (tmp->mFunObj) {
JSFunction* fun = (JSFunction*)tmp->mFunObj->getPrivate();
if (fun->atom) {
size_t size = 1 + JS_PutEscapedString(NULL, 0, ATOM_TO_STRING(fun->atom), 0);
size_t size = 1 + JS_PutEscapedFlatString(NULL, 0, ATOM_TO_STRING(fun->atom), 0);
char *name = new char[size];
if (name) {
JS_PutEscapedString(name, size, ATOM_TO_STRING(fun->atom), 0);
JS_PutEscapedFlatString(name, size, ATOM_TO_STRING(fun->atom), 0);
foo.AppendLiteral(" [");
foo.Append(name);
delete[] name;
@ -232,7 +232,7 @@ nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, PRBool *aIsInterval,
ncc->GetArgc(&argc);
ncc->GetArgvPtr(&argv);
JSString *expr = nsnull;
JSFlatString *expr = nsnull;
JSObject *funobj = nsnull;
int32 interval = 0;
@ -264,10 +264,17 @@ nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, PRBool *aIsInterval,
case JSTYPE_STRING:
case JSTYPE_OBJECT:
expr = ::JS_ValueToString(cx, argv[0]);
if (!expr)
return NS_ERROR_OUT_OF_MEMORY;
argv[0] = STRING_TO_JSVAL(expr);
{
JSString *str = ::JS_ValueToString(cx, argv[0]);
if (!str)
return NS_ERROR_OUT_OF_MEMORY;
expr = ::JS_FlattenString(cx, str);
if (!expr)
return NS_ERROR_OUT_OF_MEMORY;
argv[0] = STRING_TO_JSVAL(str);
}
break;
default:
@ -370,8 +377,7 @@ const PRUnichar *
nsJSScriptTimeoutHandler::GetHandlerText()
{
NS_ASSERTION(mExpr, "No expression, so no handler text!");
return reinterpret_cast<const PRUnichar *>
(::JS_GetStringChars(mExpr));
return ::JS_GetFlatStringChars(mExpr);
}
nsresult NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,

View File

@ -75,23 +75,44 @@ public:
class nsDependentJSString : public nsDependentString
{
public:
explicit nsDependentJSString(jsval v)
: nsDependentString((PRUnichar *)::JS_GetStringChars(JSVAL_TO_STRING(v)),
::JS_GetStringLength(JSVAL_TO_STRING(v)))
{
}
/**
* In the case of string ids, getting the string's chars is infallible, so
* the dependent string can be constructed directly.
*/
explicit nsDependentJSString(jsid id)
: nsDependentString((PRUnichar *)::JS_GetStringChars(JSID_TO_STRING(id)),
::JS_GetStringLength(JSID_TO_STRING(id)))
: nsDependentString(JS_GetInternedStringChars(JSID_TO_STRING(id)),
JS_GetStringLength(JSID_TO_STRING(id)))
{
}
explicit nsDependentJSString(JSString *str)
: nsDependentString((PRUnichar *)::JS_GetStringChars(str), ::JS_GetStringLength(str))
/**
* For all other strings, the nsDependentJSString object should be default
* constructed, which leaves it empty (this->IsEmpty()), and initialized with
* one of the fallible init() methods below.
*/
nsDependentJSString()
{
}
JSBool init(JSContext* aContext, JSString* str)
{
size_t length;
const jschar* chars = JS_GetStringCharsZAndLength(aContext, str, &length);
if (!chars)
return JS_FALSE;
NS_ASSERTION(IsEmpty(), "init() on initialized string");
nsDependentString* base = this;
new(base) nsDependentString(chars, length);
return JS_TRUE;
}
JSBool init(JSContext* aContext, const jsval &v)
{
return init(aContext, JSVAL_TO_STRING(v));
}
~nsDependentJSString()
{
}

View File

@ -425,7 +425,7 @@ IDBCursor::Continue(const jsval &aKey,
}
Key key;
nsresult rv = IDBObjectStore::GetKeyFromJSVal(aKey, key);
nsresult rv = IDBObjectStore::GetKeyFromJSVal(aKey, aCx, key);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR);
if (key.IsNull()) {
@ -504,7 +504,7 @@ IDBCursor::Update(const jsval& aValue,
}
else {
Key newKey;
rv = IDBObjectStore::GetKeyFromJSVal(prop.jsval_value(), newKey);
rv = IDBObjectStore::GetKeyFromJSVal(prop.jsval_value(), aCx, newKey);
NS_ENSURE_SUCCESS(rv, rv);
if (newKey.IsUnset() || newKey.IsNull() || newKey != key) {

View File

@ -357,7 +357,7 @@ GetKeyFromObject(JSContext* aCx,
JSBool ok = JS_GetUCProperty(aCx, aObj, keyPathChars, keyPathLen, &key);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
nsresult rv = IDBObjectStore::GetKeyFromJSVal(key, aKey);
nsresult rv = IDBObjectStore::GetKeyFromJSVal(key, aCx, aKey);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
@ -442,6 +442,7 @@ IDBObjectStore::GetKeyFromVariant(nsIVariant* aKeyVariant,
// static
nsresult
IDBObjectStore::GetKeyFromJSVal(jsval aKeyVal,
JSContext* aCx,
Key& aKey)
{
if (JSVAL_IS_VOID(aKeyVal)) {
@ -451,7 +452,11 @@ IDBObjectStore::GetKeyFromJSVal(jsval aKeyVal,
aKey = Key::NULLKEY;
}
else if (JSVAL_IS_STRING(aKeyVal)) {
aKey = nsDependentJSString(aKeyVal);
nsDependentJSString depStr;
if (!depStr.init(aCx, JSVAL_TO_STRING(aKeyVal))) {
return NS_ERROR_OUT_OF_MEMORY;
}
aKey = depStr;
}
else if (JSVAL_IS_INT(aKeyVal)) {
aKey = JSVAL_TO_INT(aKeyVal);
@ -586,7 +591,12 @@ IDBObjectStore::GetKeyPathValueFromJSON(const nsAString& aJSON,
value.jsval_addr());
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
rv = GetKeyFromJSVal(value.jsval_value(), aValue);
rv = GetKeyFromJSVal(value.jsval_value(), *aCx, aValue);
if (rv == NS_ERROR_OUT_OF_MEMORY) {
NS_ASSERTION(JS_IsExceptionPending(*aCx), "OOM from JS should throw");
return NS_ERROR_OUT_OF_MEMORY;
}
if (NS_FAILED(rv) || aValue.IsNull()) {
// If the object doesn't have a value that we can use for our index then we
// leave it unset.
@ -627,7 +637,12 @@ IDBObjectStore::GetIndexUpdateInfo(ObjectStoreInfo* aObjectStoreInfo,
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
Key value;
nsresult rv = GetKeyFromJSVal(keyPathValue, value);
nsresult rv = GetKeyFromJSVal(keyPathValue, aCx, value);
if (rv == NS_ERROR_OUT_OF_MEMORY) {
NS_ASSERTION(JS_IsExceptionPending(aCx), "OOM from JS should throw");
return NS_ERROR_OUT_OF_MEMORY;
}
if (NS_FAILED(rv) || value.IsUnset() || value.IsNull()) {
// Not a value we can do anything with, ignore it.
continue;
@ -794,7 +809,7 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
JSAutoRequest ar(aCx);
if (mKeyPath.IsEmpty()) {
rv = GetKeyFromJSVal(aKeyVal, aKey);
rv = GetKeyFromJSVal(aKeyVal, aCx, aKey);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR);
}
else {

View File

@ -78,6 +78,7 @@ public:
static nsresult
GetKeyFromJSVal(jsval aKeyVal,
JSContext* aCx,
Key& aKey);
static nsresult

View File

@ -335,7 +335,14 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
if (!isUndefined && NS_SUCCEEDED(rv)) {
NS_ASSERTION(JSVAL_IS_STRING(rval), "evalInSandbox is broken");
result = nsDependentJSString(JSVAL_TO_STRING(rval));
nsDependentJSString depStr;
if (!depStr.init(cx, JSVAL_TO_STRING(rval))) {
JS_ReportPendingException(cx);
isUndefined = PR_TRUE;
} else {
result = depStr;
}
}
stack->Pop(nsnull);

View File

@ -142,9 +142,11 @@ nsDOMWorkerFunctions::Dump(JSContext* aCx,
JSString* str;
if (aArgc && (str = JS_ValueToString(aCx, JS_ARGV(aCx, aVp)[0])) && str) {
nsDependentJSString string(str);
fputs(NS_ConvertUTF16toUTF8(nsDependentJSString(str)).get(), stderr);
fflush(stderr);
nsDependentJSString depStr;
if (depStr.init(aCx, str)) {
fputs(NS_ConvertUTF16toUTF8(depStr).get(), stderr);
fflush(stderr);
}
}
return JS_TRUE;
}
@ -268,7 +270,12 @@ nsDOMWorkerFunctions::LoadScripts(JSContext* aCx,
nsString* newURL = urls.AppendElement();
NS_ASSERTION(newURL, "Shouldn't fail if SetCapacity succeeded above!");
newURL->Assign(nsDependentJSString(str));
nsDependentJSString depStr;
if (!depStr.init(aCx, str)) {
return JS_FALSE;
}
newURL->Assign(depStr);
}
nsRefPtr<nsDOMWorkerScriptLoader> loader =
@ -507,8 +514,7 @@ nsDOMWorkerFunctions::CTypesLazyGetter(JSContext* aCx,
{
NS_ASSERTION(JS_GetGlobalForObject(aCx, aObj) == aObj, "Bad object!");
NS_ASSERTION(JSID_IS_STRING(aId), "Not a string!");
JSString* str = JSID_TO_STRING(aId);
NS_ASSERTION(nsDependentJSString(str).EqualsLiteral("ctypes"), "Bad id!");
NS_ASSERTION(nsDependentJSString(aId).EqualsLiteral("ctypes"), "Bad id!");
}
#endif
nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx));
@ -674,14 +680,14 @@ nsDOMWorkerScope::AddProperty(nsIXPConnectWrappedNative* aWrapper,
return NS_OK;
}
JSString *str = JSID_TO_STRING(aId);
JSFlatString *str = JSID_TO_FLAT_STRING(aId);
// Figure out which listener we're setting.
SetListenerFunc func;
if (JS_MatchStringAndAscii(str, "onmessage")) {
if (JS_FlatStringEqualsAscii(str, "onmessage")) {
func = &nsDOMWorkerScope::SetOnmessage;
}
else if (JS_MatchStringAndAscii(str, "onerror")) {
else if (JS_FlatStringEqualsAscii(str, "onerror")) {
func = &nsDOMWorkerScope::SetOnerror;
}
else {
@ -1302,7 +1308,10 @@ nsDOMWorker::InitializeInternal(nsIScriptGlobalObject* aOwner,
JSString* str = JS_ValueToString(aCx, aArgv[0]);
NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
mScriptURL.Assign(nsDependentJSString(str));
nsDependentJSString depStr;
NS_ENSURE_TRUE(depStr.init(aCx, str), NS_ERROR_OUT_OF_MEMORY);
mScriptURL.Assign(depStr);
NS_ENSURE_FALSE(mScriptURL.IsEmpty(), NS_ERROR_INVALID_ARG);
mLock = nsAutoLock::NewLock("nsDOMWorker::mLock");

View File

@ -196,11 +196,10 @@ nsDOMWorkerTimeout::ExpressionCallback::Run(nsDOMWorkerTimeout* aTimeout,
JSString* expression = JS_ValueToString(aCx, mExpression);
NS_ENSURE_TRUE(expression, NS_ERROR_FAILURE);
jschar* string = JS_GetStringChars(expression);
size_t stringLength;
const jschar* string = JS_GetStringCharsAndLength(aCx, expression, &stringLength);
NS_ENSURE_TRUE(string, NS_ERROR_FAILURE);
size_t stringLength = JS_GetStringLength(expression);
jsval rval;
PRBool success = JS_EvaluateUCScriptForPrincipals(aCx, global, principal,
string, stringLength,

View File

@ -278,20 +278,23 @@ SetProtocol(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSAutoRequest ar(cx);
JSString *protocol = JS_ValueToString(cx, argv[0]);
JSString *str = JS_ValueToString(cx, argv[0]);
if (!str) return JS_FALSE;
JSFlatString *protocol = JS_FlattenString(cx, str);
if (!protocol) return JS_FALSE;
if (JS_MatchStringAndAscii(protocol, "interactive")) {
if (JS_FlatStringEqualsAscii(protocol, "interactive")) {
shell->mEmitHeader = PR_FALSE;
shell->mPrompt = NS_LITERAL_CSTRING("\n> ");
shell->mProtocol = protocol;
}
else if (JS_MatchStringAndAscii(protocol, "synchronous")) {
else if (JS_FlatStringEqualsAscii(protocol, "synchronous")) {
shell->mEmitHeader = PR_TRUE;
shell->mPrompt = NS_LITERAL_CSTRING("\n> ");
shell->mProtocol = protocol;
}
else if (JS_MatchStringAndAscii(protocol, "plain")) {
else if (JS_FlatStringEqualsAscii(protocol, "plain")) {
shell->mEmitHeader = PR_FALSE;
shell->mPrompt = NS_LITERAL_CSTRING("\n");
shell->mProtocol = protocol;

View File

@ -1253,10 +1253,13 @@ XPCShellEnvironment::EvaluateString(const nsString& aString,
if (ok && result != JSVAL_VOID) {
JSErrorReporter old = JS_SetErrorReporter(mCx, NULL);
JSString* str = JS_ValueToString(mCx, result);
nsDependentJSString depStr;
if (str)
depStr.init(mCx, str);
JS_SetErrorReporter(mCx, old);
if (str && aResult) {
aResult->Assign(nsDependentJSString(str));
if (!depStr.IsEmpty() && aResult) {
aResult->Assign(depStr);
}
}
}

View File

@ -63,6 +63,11 @@ CPPSRCS = \
ObjectWrapperChild.cpp \
$(NULL)
# For nsDependentJSString
LOCAL_INCLUDES += \
-I$(topsrcdir)/dom/base \
$(NULL)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk

View File

@ -50,6 +50,7 @@
#include "nsTArray.h"
#include "nsContentUtils.h"
#include "nsIJSContextStack.h"
#include "nsJSUtils.h"
using namespace mozilla::jsipc;
using namespace js;
@ -188,8 +189,12 @@ ObjectWrapperChild::jsval_to_JSVariant(JSContext* cx, jsval from, JSVariant* to)
case JSTYPE_OBJECT:
return JSObject_to_JSVariant(cx, JSVAL_TO_OBJECT(from), to);
case JSTYPE_STRING:
*to = nsDependentString((PRUnichar*)JS_GetStringChars(JSVAL_TO_STRING(from)),
JS_GetStringLength(JSVAL_TO_STRING(from)));
{
nsDependentJSString depStr;
if (!depStr.init(cx, from))
return false;
*to = depStr;
}
return true;
case JSTYPE_NUMBER:
if (JSVAL_IS_INT(from))
@ -282,10 +287,10 @@ ObjectWrapperChild::Manager()
static bool
jsid_to_nsString(JSContext* cx, jsid from, nsString* to)
{
jsval v;
if (JS_IdToValue(cx, from, &v) && JSVAL_IS_STRING(v)) {
*to = nsDependentString((PRUnichar*)JS_GetStringChars(JSVAL_TO_STRING(v)),
JS_GetStringLength(JSVAL_TO_STRING(v)));
if (JSID_IS_STRING(from)) {
size_t length;
const jschar* chars = JS_GetInternedStringCharsAndLength(JSID_TO_STRING(from), &length);
*to = nsDependentString(chars, length);
return true;
}
return false;

View File

@ -42,6 +42,7 @@
#include "mozilla/jsipc/ContextWrapperParent.h"
#include "mozilla/jsipc/CPOWTypes.h"
#include "mozilla/unused.h"
#include "nsJSUtils.h"
#include "jsobj.h"
#include "jsfun.h"
@ -265,8 +266,12 @@ ObjectWrapperParent::jsval_to_JSVariant(JSContext* cx, jsval from,
}
return true;
case JSTYPE_STRING:
*to = nsDependentString((PRUnichar*)JS_GetStringChars(JSVAL_TO_STRING(from)),
JS_GetStringLength(JSVAL_TO_STRING(from)));
{
nsDependentJSString depStr;
if (!depStr.init(cx, from))
return false;
*to = depStr;
}
return true;
case JSTYPE_NUMBER:
if (JSVAL_IS_INT(from))
@ -379,10 +384,12 @@ static bool
jsval_to_nsString(JSContext* cx, jsid from, nsString* to)
{
JSString* str;
const jschar* chars;
jsval idval;
if (JS_IdToValue(cx, from, &idval) &&
(str = JS_ValueToString(cx, idval))) {
*to = JS_GetStringChars(str);
(str = JS_ValueToString(cx, idval)) &&
(chars = JS_GetStringCharsZ(cx, str))) {
*to = chars;
return true;
}
return false;

View File

@ -49,6 +49,8 @@
#include "mozilla/jetpack/PHandleChild.h"
#include "mozilla/jetpack/Handle.h"
#include "nsJSUtils.h"
using mozilla::jetpack::JetpackActorCommon;
using mozilla::jetpack::PHandleParent;
using mozilla::jetpack::HandleParent;
@ -138,8 +140,12 @@ JetpackActorCommon::jsval_to_PrimVariant(JSContext* cx, JSType type, jsval from,
}
case JSTYPE_STRING:
*to = nsDependentString((PRUnichar*)JS_GetStringChars(JSVAL_TO_STRING(from)),
JS_GetStringLength(JSVAL_TO_STRING(from)));
{
nsDependentJSString depStr;
if (!depStr.init(cx, from))
return false;
*to = depStr;
}
return true;
case JSTYPE_NUMBER:
@ -223,8 +229,10 @@ JetpackActorCommon::jsval_to_CompVariant(JSContext* cx, JSType type, jsval from,
KeyValue kv;
// Silently drop properties that can't be converted.
if (jsval_to_Variant(cx, val, &kv.value(), seen)) {
kv.key() = nsDependentString((PRUnichar*)JS_GetStringChars(idStr),
JS_GetStringLength(idStr));
nsDependentJSString depStr;
if (!depStr.init(cx, idStr))
return false;
kv.key() = depStr;
// If AppendElement fails, we lose this property, no big deal.
kvs.AppendElement(kv);
}

View File

@ -96,7 +96,7 @@ static char*
UnicodeToNative(JSContext *cx, const jschar *source, size_t slen)
{
nsCAutoString native;
nsDependentString unicode(reinterpret_cast<const PRUnichar*>(source), slen);
nsDependentString unicode(source, slen);
nsresult rv = NS_CopyUnicodeToNative(unicode, native);
if (NS_FAILED(rv)) {
JS_ReportError(cx, "could not convert string to native charset");
@ -251,8 +251,12 @@ MessageCommon(JSContext* cx, uintN argc, jsval* vp,
return JS_FALSE;
}
result->msgName.Assign((PRUnichar*)JS_GetStringChars(msgNameStr),
JS_GetStringLength(msgNameStr));
size_t length;
const jschar* chars = JS_GetStringCharsAndLength(cx, msgNameStr, &length);
if (!chars)
return JS_FALSE;
result->msgName.Assign(chars, length);
result->data.Clear();
@ -355,8 +359,12 @@ ReceiverCommon(JSContext* cx, uintN argc, jsval* vp,
return JS_FALSE;
}
result->msgName.Assign((PRUnichar*)JS_GetStringChars(str),
JS_GetStringLength(str));
size_t length;
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
return JS_FALSE;
result->msgName.Assign(chars, length);
if (arity < 2)
return JS_TRUE;
@ -497,9 +505,13 @@ JetpackChild::EvalInSandbox(JSContext* cx, uintN argc, jsval* vp)
return JS_FALSE;
}
size_t length;
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
return JS_FALSE;
js::AutoValueRooter ignored(cx);
return JS_EvaluateUCScript(cx, obj, JS_GetStringChars(str), JS_GetStringLength(str), "", 1,
ignored.jsval_addr());
return JS_EvaluateUCScript(cx, obj, chars, length, "", 1, ignored.jsval_addr());
}
bool JetpackChild::sReportingError;

View File

@ -74,6 +74,11 @@ CPPSRCS = \
JetpackActorCommon.cpp \
$(NULL)
# For nsDependentJSString
LOCAL_INCLUDES += \
-I$(topsrcdir)/dom/base \
$(NULL)
ifdef ENABLE_TESTS
TOOL_DIRS += tests
endif

View File

@ -214,7 +214,8 @@ _dumpJSDScript(JSDContext* jsdc, JSDScript* jsdscript, const char* leadingtext)
if (fun) {
n += size_t(snprintf(Buf + n, sizeof(Buf) - n, "%s", "no fun"));
} else {
n += JS_PutEscapedString(Buf + n, sizeof(Buf) - n, fun, 0);
n += JS_PutEscapedFlatString(Buf + n, sizeof(Buf) - n,
JS_ASSERT_STRING_IS_FLAT(fun), 0);
Buf[sizeof(Buf) - 1] = '\0';
}
if (n + 1 < sizeof(Buf))

View File

@ -562,8 +562,11 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name)
while(NULL != (jsdprop = jsd_IterateProperties(jsdc, jsdval, &iter)))
{
JSString* propName = jsd_GetValueString(jsdc, jsdprop->name);
if(propName && !JS_CompareStrings(propName, name))
return jsdprop;
if(propName) {
intN result;
if (JS_CompareStrings(cx, propName, name, &result) && !result)
return jsdprop;
}
JSD_DropProperty(jsdc, jsdprop);
}
/* Not found in property list, look it up explicitly */
@ -571,8 +574,8 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* name)
if(!(obj = JSVAL_TO_OBJECT(jsdval->val)))
return NULL;
nameChars = JS_GetStringChars(name);
nameLen = JS_GetStringLength(name);
if (!(nameChars = JS_GetStringCharsZAndLength(cx, name, &nameLen)))
return NULL;
JS_BeginRequest(cx);
call = JS_EnterCrossCompartmentCall(cx, obj);

View File

@ -1054,13 +1054,16 @@ jsdScript::CreatePPLineMap()
return nsnull;
} while(false);
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, jsstr, &length);
if (!chars)
return nsnull;
const char *argnames[] = {"arg1", "arg2", "arg3", "arg4",
"arg5", "arg6", "arg7", "arg8",
"arg9", "arg10", "arg11", "arg12" };
fun = JS_CompileUCFunction (cx, obj, "ppfun", nargs, argnames,
JS_GetStringChars(jsstr),
JS_GetStringLength(jsstr),
"x-jsd:ppbuffer?type=function", 3);
fun = JS_CompileUCFunction (cx, obj, "ppfun", nargs, argnames, chars,
length, "x-jsd:ppbuffer?type=function", 3);
if (!fun || !(script = JS_GetFunctionScript(cx, fun)))
return nsnull;
baseLine = 3;
@ -1079,9 +1082,12 @@ jsdScript::CreatePPLineMap()
return nsnull;
} while(false);
script = JS_CompileUCScript (cx, obj,
JS_GetStringChars(jsstr),
JS_GetStringLength(jsstr),
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, jsstr, &length);
if (!chars)
return nsnull;
script = JS_CompileUCScript (cx, obj, chars, length,
"x-jsd:ppbuffer?type=script", 1);
if (!script)
return nsnull;
@ -1303,8 +1309,7 @@ jsdScript::GetParameterNames(PRUint32* count, PRUnichar*** paramNames)
ret[i] = 0;
} else {
JSString *str = JS_AtomKey(atom);
ret[i] = NS_strndup(reinterpret_cast<PRUnichar*>(JS_GetStringChars(str)),
JS_GetStringLength(str));
ret[i] = NS_strndup(JS_GetInternedStringChars(str), JS_GetStringLength(str));
if (!ret[i]) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, ret);
rv = NS_ERROR_OUT_OF_MEMORY;
@ -1376,10 +1381,12 @@ jsdScript::GetFunctionSource(nsAString & aFunctionSource)
if (!jsstr)
return NS_ERROR_FAILURE;
aFunctionSource =
nsDependentString(
reinterpret_cast<PRUnichar*>(JS_GetStringChars(jsstr)),
JS_GetStringLength(jsstr));
size_t length;
const jschar *chars = JS_GetStringCharsZAndLength(cx, jsstr, &length);
if (!chars)
return NS_ERROR_FAILURE;
aFunctionSource = nsDependentString(chars, length);
return NS_OK;
}
@ -2274,12 +2281,19 @@ NS_IMETHODIMP
jsdValue::GetStringValue(nsACString &_rval)
{
ASSERT_VALID_EPHEMERAL;
JSContext *cx = JSD_GetDefaultJSContext (mCx);
if (!cx) {
NS_WARNING("No default context !?");
return NS_ERROR_FAILURE;
}
JSString *jstr_val = JSD_GetValueString(mCx, mValue);
if (jstr_val) {
nsDependentString chars(
reinterpret_cast<PRUnichar*>(JS_GetStringChars(jstr_val)),
JS_GetStringLength(jstr_val));
CopyUTF16toUTF8(chars, _rval);
size_t length;
const jschar *chars = JS_GetStringCharsZAndLength(cx, jstr_val, &length);
if (!chars)
return NS_ERROR_FAILURE;
nsDependentString depStr(chars, length);
CopyUTF16toUTF8(depStr, _rval);
} else {
_rval.Truncate();
}

View File

@ -12,28 +12,28 @@ BEGIN_TEST(testIntString_bug515273)
EVAL("'1';", v.addr());
JSString *str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JS_MatchStringAndAscii(str, "1"));
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "1"));
EVAL("'42';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JS_MatchStringAndAscii(str, "42"));
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "42"));
EVAL("'111';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JS_MatchStringAndAscii(str, "111"));
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "111"));
/* Test other types of static strings. */
EVAL("'a';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JS_MatchStringAndAscii(str, "a"));
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "a"));
EVAL("'bc';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JS_MatchStringAndAscii(str, "bc"));
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "bc"));
return true;
}

View File

@ -41,7 +41,10 @@ document_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **
return false;
if (JSVAL_IS_STRING(v.value())) {
JSString *str = JSVAL_TO_STRING(v.value());
if (JS_MatchStringAndAscii(str, "all") && !(flags & JSRESOLVE_DETECTING)) {
JSFlatString *flatStr = JS_FlattenString(cx, str);
if (!flatStr)
return false;
if (JS_FlatStringEqualsAscii(flatStr, "all") && !(flags & JSRESOLVE_DETECTING)) {
JSBool ok = JS_DefinePropertyById(cx, obj, id, JSVAL_TRUE, NULL, NULL, 0);
*objp = ok ? obj : NULL;
return ok;

View File

@ -16,7 +16,9 @@ BEGIN_TEST(testSameValue)
*/
jsval v1 = DOUBLE_TO_JSVAL(0.0);
jsval v2 = DOUBLE_TO_JSVAL(-0.0);
CHECK(!JS_SameValue(cx, v1, v2));
JSBool same;
CHECK(JS_SameValue(cx, v1, v2, &same));
CHECK(!same);
return true;
}
END_TEST(testSameValue)

View File

@ -62,7 +62,7 @@ BEGIN_TEST(testTrap_gc)
JS_GC(cx);
CHECK(JS_MatchStringAndAscii(trapClosure, trapClosureText));
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
// execute
CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
@ -70,7 +70,7 @@ BEGIN_TEST(testTrap_gc)
JS_GC(cx);
CHECK(JS_MatchStringAndAscii(trapClosure, trapClosureText));
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
return true;
}

View File

@ -192,7 +192,8 @@ class JSAPITest
bool checkSame(jsval actual, jsval expected,
const char *actualExpr, const char *expectedExpr,
const char *filename, int lineno) {
return JS_SameValue(cx, actual, expected) ||
JSBool same;
return (JS_SameValue(cx, actual, expected, &same) && same) ||
fail(JSAPITestString("CHECK_SAME failed: expected JS_SameValue(cx, ") +
actualExpr + ", " + expectedExpr + "), got !JS_SameValue(cx, " +
toSource(actual) + ", " + toSource(expected) + ")", filename, lineno);

View File

@ -581,17 +581,19 @@ JS_GetTypeName(JSContext *cx, JSType type)
}
JS_PUBLIC_API(JSBool)
JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2)
JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, JSBool *equal)
{
assertSameCompartment(cx, v1, v2);
return StrictlyEqual(cx, Valueify(v1), Valueify(v2));
*equal = StrictlyEqual(cx, Valueify(v1), Valueify(v2));
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_SameValue(JSContext *cx, jsval v1, jsval v2)
JS_SameValue(JSContext *cx, jsval v1, jsval v2, JSBool *same)
{
assertSameCompartment(cx, v1, v2);
return SameValue(Valueify(v1), Valueify(v2), cx);
*same = SameValue(Valueify(v1), Valueify(v2), cx);
return JS_TRUE;
}
/************************************************************************/
@ -5245,6 +5247,16 @@ JS_StringHasBeenInterned(JSString *str)
return str->isAtomized();
}
JS_PUBLIC_API(JSString *)
JS_InternJSString(JSContext *cx, JSString *str)
{
CHECK_REQUEST(cx);
JSAtom *atom = js_AtomizeString(cx, str, 0);
if (!atom)
return NULL;
return ATOM_TO_STRING(atom);
}
JS_PUBLIC_API(JSString *)
JS_InternString(JSContext *cx, const char *s)
{
@ -5298,45 +5310,6 @@ JS_InternUCString(JSContext *cx, const jschar *s)
return JS_InternUCStringN(cx, s, js_strlen(s));
}
JS_PUBLIC_API(jschar *)
JS_GetStringChars(JSString *str)
{
size_t n, size;
jschar *s;
str->ensureNotRope();
/*
* API botch: we have no cx to report out-of-memory when undepending
* strings, so we replace JSString::undepend with explicit malloc call and
* ignore its errors.
*
* If we fail to convert a dependent string into an independent one, our
* caller will not be guaranteed a \u0000 terminator as a backstop. This
* may break some clients who already misbehave on embedded NULs.
*
* The gain of dependent strings, which cure quadratic and cubic growth
* rate bugs in string concatenation, is worth this slight loss in API
* compatibility.
*/
if (str->isDependent()) {
n = str->dependentLength();
size = (n + 1) * sizeof(jschar);
s = (jschar *) js_malloc(size);
if (s) {
memcpy(s, str->dependentChars(), n * sizeof *s);
s[n] = 0;
str->initFlat(s, n);
} else {
s = str->dependentChars();
}
} else {
str->flatClearExtensible();
s = str->flatChars();
}
return s;
}
JS_PUBLIC_API(size_t)
JS_GetStringLength(JSString *str)
{
@ -5344,33 +5317,88 @@ JS_GetStringLength(JSString *str)
}
JS_PUBLIC_API(const jschar *)
JS_GetStringCharsAndLength(JSString *str, size_t *lengthp)
JS_GetStringCharsZ(JSContext *cx, JSString *str)
{
*lengthp = str->length();
return str->chars();
CHECK_REQUEST(cx);
assertSameCompartment(cx, str);
return str->getCharsZ(cx);
}
JS_PUBLIC_API(const jschar *)
JS_GetStringCharsZ(JSContext *cx, JSString *str)
JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *plength)
{
CHECK_REQUEST(cx);
assertSameCompartment(cx, str);
return str->undepend(cx);
*plength = str->length();
return str->getCharsZ(cx);
}
JS_PUBLIC_API(intN)
JS_CompareStrings(JSString *str1, JSString *str2)
JS_PUBLIC_API(const jschar *)
JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *plength)
{
return js_CompareStrings(str1, str2);
CHECK_REQUEST(cx);
assertSameCompartment(cx, str);
const jschar *chars;
str->getCharsAndLength(chars, *plength);
return chars;
}
JS_PUBLIC_API(const jschar *)
JS_GetInternedStringChars(JSString *str)
{
JS_ASSERT(str->isAtomized());
return str->flatChars();
}
JS_PUBLIC_API(const jschar *)
JS_GetInternedStringCharsAndLength(JSString *str, size_t *plength)
{
JS_ASSERT(str->isAtomized());
*plength = str->flatLength();
return str->flatChars();
}
extern JS_PUBLIC_API(JSFlatString *)
JS_FlattenString(JSContext *cx, JSString *str)
{
CHECK_REQUEST(cx);
assertSameCompartment(cx, str);
return str->getCharsZ(cx) ? (JSFlatString *)str : NULL;
}
extern JS_PUBLIC_API(const jschar *)
JS_GetFlatStringChars(JSFlatString *str)
{
return reinterpret_cast<JSString *>(str)->flatChars();
}
JS_PUBLIC_API(JSBool)
JS_MatchStringAndAscii(JSString *str, const char *asciiBytes)
JS_CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32 *result)
{
*result = js_CompareStrings(str1, str2);
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_StringEqualsAscii(JSContext *cx, JSString *str, const char *asciiBytes, JSBool *match)
{
return MatchStringAndAscii(str, asciiBytes);
}
JS_PUBLIC_API(JSBool)
JS_FlatStringEqualsAscii(JSFlatString *str, const char *asciiBytes)
{
return MatchStringAndAscii(str, asciiBytes);
}
JS_PUBLIC_API(size_t)
JS_PutEscapedString(char *buffer, size_t size, JSString *str, char quote)
JS_PutEscapedFlatString(char *buffer, size_t size, JSFlatString *str, char quote)
{
return PutEscapedString(buffer, size, str, quote);
}
JS_PUBLIC_API(size_t)
JS_PutEscapedString(JSContext *cx, char *buffer, size_t size, JSString *str, char quote)
{
return PutEscapedString(buffer, size, str, quote);
}
@ -5406,7 +5434,7 @@ JS_PUBLIC_API(const jschar *)
JS_UndependString(JSContext *cx, JSString *str)
{
CHECK_REQUEST(cx);
return str->undepend(cx);
return str->getCharsZ(cx);
}
JS_PUBLIC_API(JSBool)

View File

@ -702,10 +702,10 @@ extern JS_PUBLIC_API(const char *)
JS_GetTypeName(JSContext *cx, JSType type);
extern JS_PUBLIC_API(JSBool)
JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2);
JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, JSBool *equal);
extern JS_PUBLIC_API(JSBool)
JS_SameValue(JSContext *cx, jsval v1, jsval v2);
JS_SameValue(JSContext *cx, jsval v1, jsval v2, JSBool *same);
/************************************************************************/
@ -2936,6 +2936,9 @@ JS_NewStringCopyN(JSContext *cx, const char *s, size_t n);
extern JS_PUBLIC_API(JSString *)
JS_NewStringCopyZ(JSContext *cx, const char *s);
extern JS_PUBLIC_API(JSString *)
JS_InternJSString(JSContext *cx, JSString *str);
extern JS_PUBLIC_API(JSString *)
JS_InternString(JSContext *cx, const char *s);
@ -2954,36 +2957,106 @@ JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length);
extern JS_PUBLIC_API(JSString *)
JS_InternUCString(JSContext *cx, const jschar *s);
extern JS_PUBLIC_API(JSBool)
JS_CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32 *result);
extern JS_PUBLIC_API(JSBool)
JS_StringEqualsAscii(JSContext *cx, JSString *str, const char *asciiBytes, JSBool *match);
extern JS_PUBLIC_API(size_t)
JS_PutEscapedString(JSContext *cx, char *buffer, size_t size, JSString *str, char quote);
extern JS_PUBLIC_API(JSBool)
JS_FileEscapedString(FILE *fp, JSString *str, char quote);
/*
* Deprecated. Use JS_GetStringCharsZ() instead.
* Extracting string characters and length.
*
* While getting the length of a string is infallible, getting the chars can
* fail. As indicated by the lack of a JSContext parameter, there are two
* special cases where getting the chars is infallible:
*
* The first case is interned strings, i.e., strings from JS_InternString or
* JSID_TO_STRING(id), using JS_GetInternedStringChars*.
*
* The second case is "flat" strings that have been explicitly prepared in a
* fallible context by JS_FlattenString. To catch errors, a separate opaque
* JSFlatString type is returned by JS_FlattenString and expected by
* JS_GetFlatStringChars. Note, though, that this is purely a syntactic
* distinction: the input and output of JS_FlattenString are the same actual
* GC-thing so only one needs to be rooted. If a JSString is known to be flat,
* JS_ASSERT_STRING_IS_FLAT can be used to make a debug-checked cast. Example:
*
* // in a fallible context
* JSFlatString *fstr = JS_FlattenString(cx, str);
* if (!fstr)
* return JS_FALSE;
* JS_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str));
*
* // in an infallible context, for the same 'str'
* const jschar *chars = JS_GetFlatStringChars(fstr)
* JS_ASSERT(chars);
*
* The CharsZ APIs guarantee that the returned array has a null character at
* chars[length]. This can require additional copying so clients should prefer
* APIs without CharsZ if possible. The infallible functions also return
* null-terminated arrays. (There is no additional cost or non-Z alternative
* for the infallible functions, so 'Z' is left out of the identifier.)
*/
extern JS_PUBLIC_API(jschar *)
JS_GetStringChars(JSString *str);
extern JS_PUBLIC_API(size_t)
JS_GetStringLength(JSString *str);
/*
* Return the char array and length for this string. The array is not
* null-terminated.
*/
extern JS_PUBLIC_API(const jschar *)
JS_GetStringCharsAndLength(JSString *str, size_t *lengthp);
JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *length);
extern JS_PUBLIC_API(const jschar *)
JS_GetInternedStringChars(JSString *str);
extern JS_PUBLIC_API(const jschar *)
JS_GetInternedStringCharsAndLength(JSString *str, size_t *length);
extern JS_PUBLIC_API(const jschar *)
JS_GetStringCharsZ(JSContext *cx, JSString *str);
extern JS_PUBLIC_API(intN)
JS_CompareStrings(JSString *str1, JSString *str2);
extern JS_PUBLIC_API(const jschar *)
JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *length);
extern JS_PUBLIC_API(JSFlatString *)
JS_FlattenString(JSContext *cx, JSString *str);
extern JS_PUBLIC_API(const jschar *)
JS_GetFlatStringChars(JSFlatString *str);
static JS_ALWAYS_INLINE JSFlatString *
JSID_TO_FLAT_STRING(jsid id)
{
JS_ASSERT(JSID_IS_STRING(id));
return (JSFlatString *)(JSID_BITS(id));
}
static JS_ALWAYS_INLINE JSFlatString *
JS_ASSERT_STRING_IS_FLAT(JSString *str)
{
JS_ASSERT(JS_GetFlatStringChars((JSFlatString *)str));
return (JSFlatString *)str;
}
static JS_ALWAYS_INLINE JSString *
JS_FORGET_STRING_FLATNESS(JSFlatString *fstr)
{
return (JSString *)fstr;
}
/*
* Additional APIs that avoid fallibility when given a flat string.
*/
extern JS_PUBLIC_API(JSBool)
JS_MatchStringAndAscii(JSString *str, const char *asciiBytes);
JS_FlatStringEqualsAscii(JSFlatString *str, const char *asciiBytes);
extern JS_PUBLIC_API(size_t)
JS_PutEscapedString(char *buffer, size_t size, JSString *str, char quote);
extern JS_PUBLIC_API(JSBool)
JS_FileEscapedString(FILE *fp, JSString *str, char quote);
JS_PutEscapedFlatString(char *buffer, size_t size, JSFlatString *str, char quote);
/*
* This function is now obsolete and behaves the same as JS_NewUCString. Use

View File

@ -45,6 +45,7 @@
#include "jsprvtd.h"
#include "jspubtd.h"
#include "jsobj.h"
#include "jsstr.h"
/* Small arrays are dense, no matter what. */
const uintN MIN_SPARSE_INDEX = 256;

View File

@ -60,7 +60,7 @@
#define STRING_TO_ATOM(str) (JS_ASSERT(str->isAtomized()), \
(JSAtom *)str)
#define ATOM_TO_STRING(atom) ((JSString *)(atom))
#define ATOM_TO_STRING(atom) (JS_ASSERT_STRING_IS_FLAT((JSString *)(atom)))
#define ATOM_TO_JSVAL(atom) STRING_TO_JSVAL(ATOM_TO_STRING(atom))
/* Engine-internal extensions of jsid */

View File

@ -320,6 +320,12 @@ struct JSString
const jschar *undepend(JSContext *cx);
const jschar *getCharsZ(JSContext *cx) {
if (!isFlat())
return undepend(cx);
return flatChars();
}
inline bool ensureNotDependent(JSContext *cx) {
return !isDependent() || undepend(cx);
}
@ -444,6 +450,12 @@ struct JSString
}
};
struct JSFlatString : JSString
{
};
JS_STATIC_ASSERT(sizeof(JSFlatString) == sizeof(JSString));
struct JSExternalString : JSString
{
static const uintN TYPE_LIMIT = 8;

View File

@ -2692,7 +2692,7 @@ ValueToNative(const Value &v, JSValueType type, double* slot)
if (LogController.lcbits & LC_TMTracer) {
char funName[40];
if (fun->atom)
JS_PutEscapedString(funName, sizeof funName, ATOM_TO_STRING(fun->atom), 0);
JS_PutEscapedFlatString(funName, sizeof funName, ATOM_TO_STRING(fun->atom), 0);
else
strcpy(funName, "unnamed");
LogController.printf("function<%p:%s> ", (void*)*(JSObject **)slot, funName);
@ -2890,7 +2890,7 @@ NativeToValue(JSContext* cx, Value& v, JSValueType type, double* slot)
JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &v.toObject());
char funName[40];
if (fun->atom)
JS_PutEscapedString(funName, sizeof funName, ATOM_TO_STRING(fun->atom), 0);
JS_PutEscapedFlatString(funName, sizeof funName, ATOM_TO_STRING(fun->atom), 0);
else
strcpy(funName, "unnamed");
LogController.printf("function<%p:%s> ", (void*) &v.toObject(), funName);

View File

@ -266,8 +266,9 @@ typedef enum JSWhyMagic
JS_GENERIC_MAGIC /* for local use */
} JSWhyMagic;
typedef struct JSString JSString;
typedef struct JSObject JSObject;
typedef struct JSString JSString;
typedef struct JSFlatString JSFlatString;
typedef struct JSObject JSObject;
#if defined(IS_LITTLE_ENDIAN)
# if JS_BITS_PER_WORD == 32

View File

@ -1247,7 +1247,10 @@ AssertEq(JSContext *cx, uintN argc, jsval *vp)
}
jsval *argv = JS_ARGV(cx, vp);
if (!JS_SameValue(cx, argv[0], argv[1])) {
JSBool same;
if (!JS_SameValue(cx, argv[0], argv[1], &same))
return JS_FALSE;
if (!same) {
JSAutoByteString bytes0, bytes1;
const char *actual = ToSource(cx, &argv[0], &bytes0);
const char *expected = ToSource(cx, &argv[1], &bytes1);
@ -1338,6 +1341,10 @@ GCParameter(JSContext *cx, uintN argc, jsval *vp)
vp[2] = STRING_TO_JSVAL(str);
}
JSFlatString *flatStr = JS_FlattenString(cx, str);
if (!flatStr)
return JS_FALSE;
size_t paramIndex = 0;
for (;; paramIndex++) {
if (paramIndex == JS_ARRAY_LENGTH(paramMap)) {
@ -1347,7 +1354,7 @@ GCParameter(JSContext *cx, uintN argc, jsval *vp)
"gcNumber or gcTriggerFactor");
return JS_FALSE;
}
if (JS_MatchStringAndAscii(str, paramMap[paramIndex].name))
if (JS_FlatStringEqualsAscii(flatStr, paramMap[paramIndex].name))
break;
}
JSGCParamKey param = paramMap[paramIndex].param;
@ -1494,8 +1501,11 @@ CountHeap(JSContext *cx, uintN argc, jsval *vp)
str = JS_ValueToString(cx, JS_ARGV(cx, vp)[1]);
if (!str)
return JS_FALSE;
JSFlatString *flatStr = JS_FlattenString(cx, str);
if (!flatStr)
return JS_FALSE;
for (i = 0; ;) {
if (JS_MatchStringAndAscii(str, traceKindNames[i].name)) {
if (JS_FlatStringEqualsAscii(flatStr, traceKindNames[i].name)) {
traceKind = traceKindNames[i].kind;
break;
}
@ -1666,8 +1676,13 @@ TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
{
JSString *str = JSVAL_TO_STRING(closure);
JSStackFrame *caller = JS_GetScriptedCaller(cx, NULL);
if (!JS_EvaluateUCInStackFrame(cx, caller,
JS_GetStringChars(str), JS_GetStringLength(str),
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
return JSTRAP_ERROR;
if (!JS_EvaluateUCInStackFrame(cx, caller, chars, length,
caller->script()->filename,
caller->script()->lineno,
rval)) {
@ -2078,8 +2093,11 @@ Disassemble(JSContext *cx, uintN argc, jsval *vp)
bool lines = false, recursive = false;
while (argc > 0 && JSVAL_IS_STRING(argv[0])) {
JSString *str = JSVAL_TO_STRING(argv[0]);
lines |= !!JS_MatchStringAndAscii(str, "-l");
recursive |= !!JS_MatchStringAndAscii(str, "-r");
JSFlatString *flatStr = JS_FlattenString(cx, str);
if (!flatStr)
return JS_FALSE;
lines |= JS_FlatStringEqualsAscii(flatStr, "-l");
recursive |= JS_FlatStringEqualsAscii(flatStr, "-r");
if (!lines && !recursive)
break;
argv++, argc--;
@ -2319,13 +2337,16 @@ DumpStats(JSContext *cx, uintN argc, jsval *vp)
if (!str)
return JS_FALSE;
argv[i] = STRING_TO_JSVAL(str);
if (JS_MatchStringAndAscii(str, "arena")) {
JSFlatString *flatStr = JS_FlattenString(cx, str);
if (!flatStr)
return JS_FALSE;
if (JS_FlatStringEqualsAscii(flatStr, "arena")) {
#ifdef JS_ARENAMETER
JS_DumpArenaStats(stdout);
#endif
} else if (JS_MatchStringAndAscii(str, "atom")) {
} else if (JS_FlatStringEqualsAscii(flatStr, "atom")) {
js_DumpAtoms(cx, gOutFile);
} else if (JS_MatchStringAndAscii(str, "global")) {
} else if (JS_FlatStringEqualsAscii(flatStr, "global")) {
DumpScope(cx, cx->globalObject, stdout);
} else {
if (!JS_ValueToId(cx, STRING_TO_JSVAL(str), &id))
@ -2617,17 +2638,20 @@ Clear(JSContext *cx, uintN argc, jsval *vp)
static JSBool
Intern(JSContext *cx, uintN argc, jsval *vp)
{
JSString *str;
str = JS_ValueToString(cx, argc == 0 ? JSVAL_VOID : vp[2]);
JSString *str = JS_ValueToString(cx, argc == 0 ? JSVAL_VOID : vp[2]);
if (!str)
return JS_FALSE;
if (!JS_InternUCStringN(cx, JS_GetStringChars(str),
JS_GetStringLength(str))) {
return JS_FALSE;
}
*vp = JSVAL_VOID;
return JS_TRUE;
return false;
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
return false;
if (!JS_InternUCStringN(cx, chars, length))
return false;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
static JSBool
@ -2848,18 +2872,21 @@ split_getProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
if (!cpx)
return JS_TRUE;
if (JSID_IS_ATOM(id) && JS_MatchStringAndAscii(JSID_TO_STRING(id), "isInner")) {
if (JSID_IS_ATOM(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "isInner")) {
*vp = BOOLEAN_TO_JSVAL(cpx->isInner);
return JS_TRUE;
}
if (!cpx->isInner && cpx->inner) {
if (JSID_IS_ATOM(id)) {
JSString *str;
JSString *str = JSID_TO_STRING(id);
str = JSID_TO_STRING(id);
return JS_GetUCProperty(cx, cpx->inner, JS_GetStringChars(str),
JS_GetStringLength(str), vp);
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
return false;
return JS_GetUCProperty(cx, cpx->inner, chars, length, vp);
}
if (JSID_IS_INT(id))
return JS_GetElement(cx, cpx->inner, JSID_TO_INT(id), vp);
@ -2876,21 +2903,24 @@ split_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
cpx = split_get_private(cx, obj);
if (!cpx)
return JS_TRUE;
return true;
if (!cpx->isInner && cpx->inner) {
if (JSID_IS_ATOM(id)) {
JSString *str;
JSString *str = JSID_TO_STRING(id);
str = JSID_TO_STRING(id);
return JS_SetUCProperty(cx, cpx->inner, JS_GetStringChars(str),
JS_GetStringLength(str), vp);
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
return false;
return JS_SetUCProperty(cx, cpx->inner, chars, length, vp);
}
if (JSID_IS_INT(id))
return JS_SetElement(cx, cpx->inner, JSID_TO_INT(id), vp);
return JS_TRUE;
return true;
}
return JS_TRUE;
return true;
}
static JSBool
@ -2975,7 +3005,7 @@ split_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **obj
{
ComplexObject *cpx;
if (JSID_IS_ATOM(id) && JS_MatchStringAndAscii(JSID_TO_STRING(id), "isInner")) {
if (JSID_IS_ATOM(id) && JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), "isInner")) {
*objp = obj;
return JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, NULL, NULL, JSPROP_SHARED);
}
@ -3282,8 +3312,11 @@ EvalInContext(JSContext *cx, uintN argc, jsval *vp)
if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S / o", &str, &sobj))
return false;
const jschar *src = JS_GetStringChars(str);
size_t srclen = JS_GetStringLength(str);
size_t srclen;
const jschar *src = JS_GetStringCharsAndLength(cx, str, &srclen);
if (!src)
return false;
bool split = false, lazy = false;
if (srclen == 4) {
if (src[0] == 'l' && src[1] == 'a' && src[2] == 'z' && src[3] == 'y') {
@ -4546,8 +4579,11 @@ Help(JSContext *cx, uintN argc, jsval *vp)
str = NULL;
}
if (str) {
JSFlatString *flatStr = JS_FlattenString(cx, str);
if (!flatStr)
return JS_FALSE;
for (j = 0; shell_functions[j].name; j++) {
if (JS_MatchStringAndAscii(str, shell_functions[j].name)) {
if (JS_FlatStringEqualsAscii(flatStr, shell_functions[j].name)) {
if (!did_header) {
did_header = 1;
fputs(shell_help_header, gOutFile);

View File

@ -200,7 +200,11 @@ Dump(JSContext *cx, uintN argc, jsval *vp)
if (!str)
return JS_FALSE;
jschar *chars = JS_GetStringChars(str);
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
return JS_FALSE;
fputs(NS_ConvertUTF16toUTF8(reinterpret_cast<const PRUnichar*>(chars)).get(), stderr);
return JS_TRUE;
}

View File

@ -721,8 +721,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
JSString* str = JS_GetFunctionId(fun);
if(str)
{
NS_ConvertUTF16toUTF8
fname(reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str)));
NS_ConvertUTF16toUTF8 fname(JS_GetInternedStringChars(str));
JS_snprintf(name, sizeof(name),
"JS Object (Function - %s)", fname.get());
}

View File

@ -1137,20 +1137,33 @@ traceableArgumentConversionTemplates = {
'double':
" jsdouble ${name} = ${argVal};\n",
'[astring]':
" XPCReadableJSStringWrapper ${name}(${argVal});\n",
" XPCReadableJSStringWrapper ${name};\n"
" if (!${name}.init(cx, ${argVal})) {\n"
"${error}",
'[domstring]':
" XPCReadableJSStringWrapper ${name}(${argVal});\n",
" XPCReadableJSStringWrapper ${name};\n"
" if (!${name}.init(cx, ${argVal})) {\n"
"${error}",
'[utf8string]':
" NS_ConvertUTF16toUTF8 ${name}("
"(const PRUnichar *)JS_GetStringChars(${argVal}), "
"JS_GetStringLength(${argVal}));\n",
" size_t ${name}_length;\n"
" const jschar *${name}_chars = JS_GetStringCharsAndLength(cx, "
"${argVal}, &${name}_length);\n"
" if (!${name}_chars) {\n"
"${error}"
" NS_ConvertUTF16toUTF8 ${name}(${argVal}_chars, ${argVal}_length);\n",
'string':
" NS_ConvertUTF16toUTF8 ${name}_utf8("
"(const PRUnichar *)JS_GetStringChars(${argVal}), "
"JS_GetStringLength(${argVal}));\n"
" size_t ${name}_length;\n"
" const jschar *${name}_chars = JS_GetStringCharsAndLength(cx, "
"${argVal}, &${name}_length);\n"
" if (!${name}_chars) {\n"
"${error}"
" NS_ConvertUTF16toUTF8 ${name}_utf8(${name}_chars, ${name}_length);\n"
" const char *${name} = ${name}_utf8.get();\n",
'wstring':
" const PRUnichar *${name} = JS_GetStringChars({argVal});\n",
" const jschar *${name}_chars = JS_GetStringCharsZ(cx, {argVal});\n"
" if (!${name}_chars) {\n"
"${error}"
" const PRUnichar *${name} = ${name}_chars;\n",
}
def writeTraceableArgumentConversion(f, member, i, name, type, haveCcx,
@ -1159,7 +1172,8 @@ def writeTraceableArgumentConversion(f, member, i, name, type, haveCcx,
params = {
'name': name,
'argVal': argVal
'argVal': argVal,
'error': getFailureString(getTraceInfoDefaultReturn(member.realtype), 2)
}
typeName = getBuiltinOrNativeTypeName(type)

View File

@ -673,11 +673,10 @@ nsXPCComponents_InterfacesByID::NewResolve(nsIXPConnectWrappedNative *wrapper,
if(mManager &&
JSID_IS_STRING(id) &&
38 == JS_GetStringLength(JSID_TO_STRING(id)) &&
nsnull != (name = JS_GetStringChars(JSID_TO_STRING(id))))
nsnull != (name = JS_GetInternedStringChars(JSID_TO_STRING(id))))
{
nsID iid;
if (!iid.Parse(NS_ConvertUTF16toUTF8(reinterpret_cast<const PRUnichar*>
(name)).get()))
if (!iid.Parse(NS_ConvertUTF16toUTF8(name).get()))
return NS_OK;
nsCOMPtr<nsIInterfaceInfo> info;
@ -2958,8 +2957,11 @@ nsXPCComponents_Utils::ReportError()
frame->GetLineNumber(&lineNo);
}
rv = scripterr->Init(reinterpret_cast<const PRUnichar*>
(JS_GetStringChars(msgstr)),
const jschar *msgchars = JS_GetStringCharsZ(cx, msgstr);
if (!msgchars)
return NS_OK;
rv = scripterr->Init(msgchars,
NS_ConvertUTF8toUTF16(fileName).get(),
nsnull,
lineNo, 0,
@ -2996,12 +2998,12 @@ SandboxDump(JSContext *cx, uintN argc, jsval *vp)
if (!str)
return JS_FALSE;
jschar *chars = JS_GetStringChars(str);
size_t length;
const jschar *chars = JS_GetStringCharsZAndLength(cx, str, &length);
if (!chars)
return JS_FALSE;
nsDependentString wstr(reinterpret_cast<PRUnichar *>(chars),
JS_GetStringLength(str));
nsDependentString wstr(chars, length);
char *cstr = ToNewUTF8String(wstr);
if (!cstr)
return JS_FALSE;
@ -3332,10 +3334,15 @@ nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrappe
nsCOMPtr<nsIPrincipal> principal;
nsISupports *prinOrSop = nsnull;
if (JSVAL_IS_STRING(argv[0])) {
JSString *codebasestr = JSVAL_TO_STRING(argv[0]);
nsAutoString codebase(reinterpret_cast<PRUnichar*>
(JS_GetStringChars(codebasestr)),
JS_GetStringLength(codebasestr));
JSString *codebaseStr = JSVAL_TO_STRING(argv[0]);
size_t codebaseLength;
const jschar *codebaseChars = JS_GetStringCharsAndLength(cx, codebaseStr,
&codebaseLength);
if (!codebaseChars) {
return ThrowAndFail(NS_ERROR_FAILURE, cx, _retval);
}
nsAutoString codebase(codebaseChars, codebaseLength);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), codebase);
if (NS_FAILED(rv)) {

View File

@ -174,7 +174,8 @@ FinalizeXPCOMUCString(JSContext *cx, JSString *str)
NS_ASSERTION(sXPCOMUCStringFinalizerIndex != -1,
"XPCConvert: XPCOM Unicode string finalizer called uninitialized!");
jschar* buffer = JS_GetStringChars(str);
jschar* buffer = const_cast<jschar *>(JS_GetStringCharsZ(cx, str));
NS_ASSERTION(buffer, "How could this OOM if we allocated the memory?");
nsMemory::Free(buffer);
}
@ -613,25 +614,35 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
{
return JS_FALSE;
}
jschar ch = JS_GetStringLength(str) ? JS_GetStringChars(str)[0] : 0;
size_t length;
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
{
return JS_FALSE;
}
jschar ch = length ? chars[0] : 0;
NS_ASSERTION(!ILLEGAL_RANGE(ch), "U+0080/U+0100 - U+FFFF data lost");
*((char*)d) = char(ch);
break;
}
case nsXPTType::T_WCHAR :
{
const jschar* chars=nsnull;
JSString* str;
if(!(str = JS_ValueToString(cx, s)))
{
return JS_FALSE;
}
if(JS_GetStringLength(str) == 0)
size_t length;
const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
{
return JS_FALSE;
}
if(length == 0)
{
*((uint16*)d) = 0;
break;
}
chars = JS_GetStringChars(str);
*((uint16*)d) = (uint16) chars[0];
break;
}
@ -729,7 +740,7 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
length = (PRUint32) JS_GetStringLength(str);
if(length)
{
chars = (const PRUnichar*) JS_GetStringChars(str);
chars = JS_GetStringCharsZ(cx, str);
if(!chars)
return JS_FALSE;
if(STRING_TO_JSVAL(str) != s)
@ -747,8 +758,13 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
// XXX extra string copy when isNewString
if(str && !isNewString)
{
size_t strLength;
const jschar *strChars = JS_GetStringCharsZAndLength(cx, str, &strLength);
if (!strChars)
return JS_FALSE;
XPCReadableJSStringWrapper *wrapper =
XPCStringConvert::JSStringToReadable(ccx, str);
ccx.NewStringWrapper(strChars, strLength);
if(!wrapper)
return JS_FALSE;
@ -815,12 +831,12 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
return JS_FALSE;
}
#ifdef DEBUG
jschar* chars=nsnull;
if(nsnull != (chars = JS_GetStringChars(str)))
const jschar* chars=nsnull;
if(nsnull != (chars = JS_GetStringCharsZ(cx, str)))
{
PRBool legalRange = PR_TRUE;
int len = JS_GetStringLength(str);
jschar* t;
const jschar* t;
PRInt32 i=0;
for(t=chars; (i< len) && legalRange ; i++,t++) {
if(ILLEGAL_RANGE(*t))
@ -869,7 +885,7 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
}
if(useAllocator)
{
if(!(chars = JS_GetStringChars(str)))
if(!(chars = JS_GetStringCharsZ(cx, str)))
{
return JS_FALSE;
}
@ -898,7 +914,7 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
case nsXPTType::T_UTF8STRING:
{
jschar* chars;
const jschar* chars;
PRUint32 length;
JSString* str;
@ -925,7 +941,7 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
// The JS val is neither null nor void...
if(!(str = JS_ValueToString(cx, s))||
!(chars = JS_GetStringChars(str)))
!(chars = JS_GetStringCharsZ(cx, str)))
{
return JS_FALSE;
}
@ -1029,8 +1045,7 @@ XPCConvert::JSData2Native(XPCCallContext& ccx, void* d, jsval s,
{
// We're trying to pass a string as an nsIAtom. Let's atomize!
JSString* str = JSVAL_TO_STRING(s);
PRUnichar* chars =
reinterpret_cast<PRUnichar*>(JS_GetStringChars(str));
const PRUnichar* chars = JS_GetStringCharsZ(cx, str);
if (!chars) {
if (pErr)
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF;
@ -2412,7 +2427,7 @@ XPCConvert::JSStringWithSize2Native(XPCCallContext& ccx, void* d, jsval s,
if(useAllocator)
{
if(!(chars = JS_GetStringChars(str)))
if(!(chars = JS_GetStringCharsZ(cx, str)))
{
return JS_FALSE;
}

View File

@ -1016,10 +1016,17 @@ public:
nsDependentString(char_traits::sEmptyBuffer, char_traits::sEmptyBuffer)
{ SetIsVoid(PR_TRUE); }
explicit XPCReadableJSStringWrapper(JSString *str) :
nsDependentString(reinterpret_cast<const PRUnichar *>(::JS_GetStringChars(str)),
str->length())
{ }
JSBool init(JSContext* aContext, JSString* str)
{
size_t length;
const jschar* chars = JS_GetStringCharsZAndLength(aContext, str, &length);
if (!chars)
return JS_FALSE;
NS_ASSERTION(IsEmpty(), "init() on initialized string");
new(static_cast<nsDependentString *>(this)) nsDependentString(chars, length);
return JS_TRUE;
}
};
// No virtuals
@ -1133,8 +1140,7 @@ public:
operator JSContext*() const {return GetJSContext();}
XPCReadableJSStringWrapper *NewStringWrapper(const PRUnichar *str,
PRUint32 len);
XPCReadableJSStringWrapper *NewStringWrapper(const PRUnichar *str, PRUint32 len);
void DeleteString(nsAString *string);
#ifdef XPC_IDISPATCH_SUPPORT
@ -3338,9 +3344,6 @@ public:
static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
nsStringBuffer** sharedBuffer);
static XPCReadableJSStringWrapper *JSStringToReadable(XPCCallContext& ccx,
JSString *str);
static void ShutdownDOMStringFinalizer();
private:

View File

@ -701,10 +701,11 @@ xpc_qsDOMString::xpc_qsDOMString(JSContext *cx, jsval v, jsval *pval,
if (!s)
return;
size_t len = s->length();
const PRUnichar* chars =
(len == 0 ? traits::sEmptyBuffer :
reinterpret_cast<const PRUnichar*>(JS_GetStringChars(s)));
size_t len;
const jschar *chars = JS_GetStringCharsZAndLength(cx, s, &len);
if (!chars)
return;
new(mBuf) implementation_type(chars, len);
mValid = JS_TRUE;
}
@ -746,9 +747,10 @@ xpc_qsAUTF8String::xpc_qsAUTF8String(JSContext *cx, jsval v, jsval *pval)
if (!s)
return;
size_t len = s->length();
const PRUnichar* chars =
reinterpret_cast<const PRUnichar*>(JS_GetStringChars(s));
size_t len;
const PRUnichar *chars = JS_GetStringCharsZAndLength(cx, s, &len);
if (!chars)
return;
new(mBuf) implementation_type(chars, len);
mValid = JS_TRUE;
@ -1033,8 +1035,12 @@ xpc_qsJsvalToWcharStr(JSContext *cx, jsval v, jsval *pval, PRUnichar **pstr)
*pval = STRING_TO_JSVAL(str); // Root the new string.
}
const jschar *chars = JS_GetStringCharsZ(cx, str);
if (!chars)
return JS_FALSE;
// XXXbz this is casting away constness too... That seems like a bad idea.
*pstr = (PRUnichar*)JS_GetStringChars(str);
*pstr = const_cast<jschar *>(chars);
return JS_TRUE;
}

View File

@ -60,7 +60,9 @@ static int sDOMStringFinalizerIndex = -1;
static void
DOMStringFinalizer(JSContext *cx, JSString *str)
{
nsStringBuffer::FromData(JS_GetStringChars(str))->Release();
jschar *chars = const_cast<jschar *>(JS_GetStringCharsZ(cx, str));
NS_ASSERTION(chars, "How could this OOM if we allocated the memory?");
nsStringBuffer::FromData(chars)->Release();
}
void
@ -139,15 +141,3 @@ XPCStringConvert::ReadableToJSVal(JSContext *cx,
}
return STRING_TO_JSVAL(str);
}
// static
XPCReadableJSStringWrapper *
XPCStringConvert::JSStringToReadable(XPCCallContext& ccx, JSString *str)
{
const PRUnichar *chars =
reinterpret_cast<const PRUnichar *>(JS_GetStringCharsZ(ccx, str));
if(!chars)
return nsnull;
return ccx.NewStringWrapper(chars, JS_GetStringLength(str));
}

View File

@ -327,11 +327,17 @@ JSBool XPCVariant::InitializeData(XPCCallContext& ccx)
NS_ASSERTION(mData.mType == nsIDataType::VTYPE_EMPTY,
"Why do we already have data?");
mData.u.wstr.mWStringValue =
reinterpret_cast<PRUnichar*>(JS_GetStringChars(str));
// Despite the fact that the variant holds the length, there are
// implicit assumptions that mWStringValue[mWStringLength] == 0
size_t length;
const jschar *chars = JS_GetStringCharsZAndLength(ccx, str, &length);
if (!chars)
return JS_FALSE;
mData.u.wstr.mWStringValue = const_cast<jschar *>(chars);
// Use C-style cast, because reinterpret cast from size_t to
// PRUint32 is not valid on some platforms.
mData.u.wstr.mWStringLength = (PRUint32)JS_GetStringLength(str);
mData.u.wstr.mWStringLength = (PRUint32)length;
mData.mType = nsIDataType::VTYPE_WSTRING_SIZE_IS;
return JS_TRUE;

View File

@ -452,10 +452,13 @@ nsXPCWrappedJSClass::BuildPropertyEnumerator(XPCCallContext& ccx,
if(!name)
goto out;
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, name, &length);
if (!chars)
goto out;
nsCOMPtr<nsIProperty> property =
new xpcProperty((const PRUnichar*) JS_GetStringChars(name),
(PRUint32) JS_GetStringLength(name),
value);
new xpcProperty(chars, (PRUint32) length, value);
if(!property)
goto out;

View File

@ -552,11 +552,11 @@ TestArgFormatter(JSContext* jscontext, JSObject* glob, nsIXPConnect* xpc)
const char* e_in = "another meaningless chunck of text";
JSString* a_out;
JSBool a_match;
nsCOMPtr<nsISupports> b_out;
nsCOMPtr<nsIVariant> c_out;
nsAutoString d_out;
JSString* e_out;
JSBool e_match;
nsCOMPtr<nsITestXPCFoo> specified;
PRInt32 val;
@ -588,6 +588,7 @@ TestArgFormatter(JSContext* jscontext, JSObject* glob, nsIXPConnect* xpc)
return;
}
JSString *a_out, *e_out;
ok = JS_ConvertArguments(jscontext, 5, argv, "S %ip %iv %is S",
&a_out,
static_cast<nsISupports**>(getter_AddRefs(b_out)),
@ -604,11 +605,13 @@ TestArgFormatter(JSContext* jscontext, JSObject* glob, nsIXPConnect* xpc)
TAF_CHECK(c_out, " JS to native for %%iv returned NULL -- FAILED!\n");
TAF_CHECK(NS_SUCCEEDED(c_out->GetAsInt32(&val)) && val == 5, " JS to native for %%iv holds wrong value -- FAILED!\n");
TAF_CHECK(d_in.Equals(d_out), " JS to native for %%is returned the wrong value -- FAILED!\n");
TAF_CHECK(JS_StringEqualsAscii(jscontext, a_out, a_in, &a_match), " oom -- FAILED!\n");
TAF_CHECK(JS_StringEqualsAscii(jscontext, e_out, e_in, &e_match), " oom -- FAILED!\n");
} while (0);
if (!ok)
return;
if(JS_MatchStringAndAscii(a_out, a_in) && JS_MatchStringAndAscii(e_out, e_in))
if(a_match && e_match)
printf("passed\n");
else
printf(" conversion OK, but surrounding was mangled -- FAILED!\n");

View File

@ -109,18 +109,18 @@ AccessCheck::getPrincipal(JSCompartment *compartment)
#define NAME(ch, str, cases) \
case ch: if (!strcmp(name, str)) switch (propChars[0]) { cases }; break;
#define PROP(ch, actions) case ch: { actions }; break;
#define RW(str) if (JS_MatchStringAndAscii(prop, str)) return true;
#define R(str) if (!set && JS_MatchStringAndAscii(prop, str)) return true;
#define W(str) if (set && JS_MatchStringAndAscii(prop, str)) return true;
#define RW(str) if (JS_FlatStringEqualsAscii(prop, str)) return true;
#define R(str) if (!set && JS_FlatStringEqualsAscii(prop, str)) return true;
#define W(str) if (set && JS_FlatStringEqualsAscii(prop, str)) return true;
// Hardcoded policy for cross origin property access. This was culled from the
// preferences file (all.js). We don't want users to overwrite highly sensitive
// security policies.
static bool
IsPermitted(const char *name, JSString *prop, bool set)
IsPermitted(const char *name, JSFlatString *prop, bool set)
{
size_t propLength;
const jschar *propChars = JS_GetStringCharsAndLength(prop, &propLength);
const jschar *propChars = JS_GetInternedStringCharsAndLength(prop, &propLength);
if (!propLength)
return false;
switch(name[0]) {
@ -183,8 +183,7 @@ IsFrameId(JSContext *cx, JSObject *obj, jsid id)
if (JSID_IS_INT(id)) {
col->Item(JSID_TO_INT(id), getter_AddRefs(domwin));
} else if (JSID_IS_ATOM(id)) {
nsAutoString str(reinterpret_cast<PRUnichar *>
(JS_GetStringChars(ATOM_TO_STRING(JSID_TO_ATOM(id)))));
nsAutoString str(JS_GetInternedStringChars(JSID_TO_STRING(id)));
col->NamedItem(str, getter_AddRefs(domwin));
} else {
return false;
@ -291,7 +290,7 @@ AccessCheck::isCrossOriginAccessPermitted(JSContext *cx, JSObject *wrapper, jsid
name = clasp->name;
if (JSID_IS_ATOM(id)) {
if (IsPermitted(name, JSID_TO_STRING(id), act == JSWrapper::SET))
if (IsPermitted(name, JSID_TO_FLAT_STRING(id), act == JSWrapper::SET))
return true;
}
@ -418,7 +417,9 @@ AccessCheck::deny(JSContext *cx, jsid id)
JSString *str = JS_ValueToString(cx, idval);
if (!str)
return;
JS_ReportError(cx, "Permission denied to access property '%hs'", JS_GetStringChars(str));
const jschar *chars = JS_GetStringCharsZ(cx, str);
if (chars)
JS_ReportError(cx, "Permission denied to access property '%hs'", chars);
}
}
@ -480,8 +481,11 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, JSWrappe
}
JSString *str = JSVAL_TO_STRING(desc.value);
const jschar *chars = JS_GetStringChars(str);
size_t length = JS_GetStringLength(str);
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars)
return false;
for (size_t i = 0; i < length; ++i) {
switch (chars[i]) {
case 'r':

View File

@ -463,8 +463,13 @@ JSValToNPVariant(NPP npp, JSContext *cx, jsval val, NPVariant *variant)
}
} else if (JSVAL_IS_STRING(val)) {
JSString *jsstr = JSVAL_TO_STRING(val);
nsDependentString str((PRUnichar *)::JS_GetStringChars(jsstr),
::JS_GetStringLength(jsstr));
size_t length;
const jschar *chars = ::JS_GetStringCharsZAndLength(cx, jsstr, &length);
if (!chars) {
return false;
}
nsDependentString str(chars, length);
PRUint32 len;
char *p = ToNewUTF8String(str, &len);
@ -603,16 +608,9 @@ nsJSObjWrapper::NP_Invalidate(NPObject *npobj)
static JSBool
GetProperty(JSContext *cx, JSObject *obj, NPIdentifier id, jsval *rval)
{
if (NPIdentifierIsString(id)) {
JSString *str = NPIdentifierToString(id);
return ::JS_GetUCProperty(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), rval);
}
NS_ASSERTION(NPIdentifierIsInt(id), "id must be either string or int!\n");
return ::JS_GetElement(cx, obj, NPIdentifierToInt(id), rval);
NS_ASSERTION(NPIdentifierIsInt(id) || NPIdentifierIsString(id),
"id must be either string or int!\n");
return ::JS_GetPropertyById(cx, obj, NPIdentifierToJSId(id), rval);
}
// static
@ -796,17 +794,9 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier id)
if (!ac.enter(cx, npjsobj->mJSObj))
return PR_FALSE;
if (NPIdentifierIsString(id)) {
JSString *str = NPIdentifierToString(id);
ok = ::JS_HasUCProperty(cx, npjsobj->mJSObj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), &found);
} else {
NS_ASSERTION(NPIdentifierIsInt(id), "id must be either string or int!\n");
ok = ::JS_HasElement(cx, npjsobj->mJSObj, NPIdentifierToInt(id), &found);
}
NS_ASSERTION(NPIdentifierIsInt(id) || NPIdentifierIsString(id),
"id must be either string or int!\n");
ok = ::JS_HasPropertyById(cx, npjsobj->mJSObj, NPIdentifierToJSId(id), &found);
return ok && found;
}
@ -877,16 +867,9 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier id,
jsval v = NPVariantToJSVal(npp, cx, value);
js::AutoValueRooter tvr(cx, v);
if (NPIdentifierIsString(id)) {
JSString *str = NPIdentifierToString(id);
ok = ::JS_SetUCProperty(cx, npjsobj->mJSObj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), &v);
} else {
NS_ASSERTION(NPIdentifierIsInt(id), "id must be either string or int!\n");
ok = ::JS_SetElement(cx, npjsobj->mJSObj, NPIdentifierToInt(id), &v);
}
NS_ASSERTION(NPIdentifierIsInt(id) || NPIdentifierIsString(id),
"id must be either string or int!\n");
ok = ::JS_SetPropertyById(cx, npjsobj->mJSObj, NPIdentifierToJSId(id), &v);
// return ok == JS_TRUE to quiet down compiler warning, even if
// return ok is what we really want.
@ -923,45 +906,21 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier id)
if (!ac.enter(cx, npjsobj->mJSObj))
return PR_FALSE;
if (NPIdentifierIsString(id)) {
JSString *str = NPIdentifierToString(id);
NS_ASSERTION(NPIdentifierIsInt(id) || NPIdentifierIsString(id),
"id must be either string or int!\n");
ok = ::JS_DeletePropertyById2(cx, npjsobj->mJSObj, NPIdentifierToJSId(id), &deleted);
if (ok && deleted == JSVAL_TRUE) {
// FIXME: See bug 425823, we shouldn't need to do this, and once
// that bug is fixed we can remove this code.
ok = ::JS_DeleteUCProperty2(cx, npjsobj->mJSObj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), &deleted);
JSBool hasProp;
ok = ::JS_HasPropertyById(cx, npjsobj->mJSObj, NPIdentifierToJSId(id), &hasProp);
if (ok && deleted == JSVAL_TRUE) {
// FIXME: See bug 425823, we shouldn't need to do this, and once
// that bug is fixed we can remove this code.
if (ok && hasProp) {
// The property might have been deleted, but it got
// re-resolved, so no, it's not really deleted.
JSBool hasProp;
ok = ::JS_HasUCProperty(cx, npjsobj->mJSObj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), &hasProp);
if (ok && hasProp) {
// The property might have been deleted, but it got
// re-resolved, so no, it's not really deleted.
deleted = JSVAL_FALSE;
}
}
} else {
NS_ASSERTION(NPIdentifierIsInt(id), "id must be either string or int!\n");
ok = ::JS_DeleteElement2(cx, npjsobj->mJSObj, NPIdentifierToInt(id), &deleted);
if (ok && deleted == JSVAL_TRUE) {
// FIXME: See bug 425823, we shouldn't need to do this, and once
// that bug is fixed we can remove this code.
JSBool hasProp;
ok = ::JS_HasElement(cx, npjsobj->mJSObj, NPIdentifierToInt(id), &hasProp);
if (ok && hasProp) {
// The property might have been deleted, but it got
// re-resolved, so no, it's not really deleted.
deleted = JSVAL_FALSE;
}
deleted = JSVAL_FALSE;
}
}
@ -1027,14 +986,12 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray,
NPIdentifier id;
if (JSVAL_IS_STRING(v)) {
JSString *str = JSVAL_TO_STRING(v);
JSString *str = JS_InternJSString(cx, JSVAL_TO_STRING(v));
if (!str) {
::JS_DestroyIdArray(cx, ida);
PR_Free(*idarray);
if (!JS_InternUCStringN(cx, ::JS_GetStringChars(str),
::JS_GetStringLength(str))) {
::JS_DestroyIdArray(cx, ida);
PR_Free(*idarray);
return PR_FALSE;
return PR_FALSE;
}
id = StringToNPIdentifier(str);
} else {
@ -1693,21 +1650,11 @@ NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
return JS_FALSE;
if (hasProperty) {
JSBool ok;
if (JSID_IS_STRING(id)) {
JSString *str = JSID_TO_STRING(id);
ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), JSVAL_VOID, nsnull,
nsnull, JSPROP_ENUMERATE);
} else {
ok = ::JS_DefineElement(cx, obj, JSID_TO_INT(id), JSVAL_VOID, nsnull,
nsnull, JSPROP_ENUMERATE);
}
if (!ok) {
return JS_FALSE;
NS_ASSERTION(JSID_IS_STRING(id) || JSID_IS_INT(id),
"id must be either string or int!\n");
if (!::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, nsnull,
nsnull, JSPROP_ENUMERATE)) {
return JS_FALSE;
}
*objp = obj;
@ -1720,29 +1667,11 @@ NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
return JS_FALSE;
if (hasMethod) {
JSString *str = nsnull;
NS_ASSERTION(JSID_IS_STRING(id) || JSID_IS_INT(id),
"id must be either string or int!\n");
if (JSID_IS_STRING(id)) {
str = JSID_TO_STRING(id);
} else {
NS_ASSERTION(JSID_IS_INT(id), "id must be either string or int!\n");
jsval idval;
if (!JS_IdToValue(cx, id, &idval))
return JS_FALSE;
str = ::JS_ValueToString(cx, idval);
if (!str) {
// OOM. The JS engine throws exceptions for us in this case.
return JS_FALSE;
}
}
JSFunction *fnc =
::JS_DefineUCFunction(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), CallNPMethod, 0,
JSPROP_ENUMERATE);
JSFunction *fnc = ::JS_DefineFunctionById(cx, obj, id, CallNPMethod, 0,
JSPROP_ENUMERATE);
*objp = obj;

View File

@ -1441,7 +1441,7 @@ _utf8fromidentifier(NPIdentifier id)
JSString *str = NPIdentifierToString(id);
return
ToNewUTF8String(nsDependentString((PRUnichar *)::JS_GetStringChars(str),
ToNewUTF8String(nsDependentString(::JS_GetInternedStringChars(str),
::JS_GetStringLength(str)));
}

View File

@ -83,9 +83,11 @@ CPPSRCS = \
VacuumManager.cpp \
$(NULL)
# For nsDependentJSString
LOCAL_INCLUDES = \
$(SQLITE_CFLAGS) \
-I$(topsrcdir)/db/sqlite3/src \
-I$(topsrcdir)/dom/base \
$(NULL)
# This is the default value. If we ever change it when compiling sqlite, we

View File

@ -136,7 +136,7 @@ AsyncStatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper,
}
#endif
if (::JS_MatchStringAndAscii(JSID_TO_STRING(aId), "params"))
if (::JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(aId), "params"))
return getParams(stmt, aCtx, aScopeObj, _result);
return NS_OK;

View File

@ -97,9 +97,9 @@ AsyncStatementParams::SetProperty(
}
else if (JSID_IS_STRING(aId)) {
JSString *str = JSID_TO_STRING(aId);
NS_ConvertUTF16toUTF8 name(reinterpret_cast<const PRUnichar *>
(::JS_GetStringChars(str)),
::JS_GetStringLength(str));
size_t length;
const jschar *chars = JS_GetInternedStringCharsAndLength(str, &length);
NS_ConvertUTF16toUTF8 name(chars, length);
nsCOMPtr<nsIVariant> variant(convertJSValToVariant(aCtx, *_vp));
NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED);
@ -141,8 +141,8 @@ AsyncStatementParams::NewResolve(
}
else if (JSID_IS_STRING(aId)) {
JSString *str = JSID_TO_STRING(aId);
jschar *nameChars = ::JS_GetStringChars(str);
size_t nameLength = ::JS_GetStringLength(str);
size_t nameLength;
const jschar *nameChars = ::JS_GetInternedStringCharsAndLength(str, &nameLength);
// We are unable to tell if there's a parameter with this name and so
// we must assume that there is. This screws the rest of the prototype

View File

@ -49,6 +49,7 @@
#include "mozilla/Mutex.h"
#include "mozilla/CondVar.h"
#include "nsThreadUtils.h"
#include "nsJSUtils.h"
#include "Variant.h"
#include "mozStoragePrivateHelpers.h"
@ -151,10 +152,9 @@ convertJSValToVariant(
if (JSVAL_IS_STRING(aValue)) {
JSString *str = JSVAL_TO_STRING(aValue);
nsDependentString value(
reinterpret_cast<PRUnichar *>(::JS_GetStringChars(str)),
::JS_GetStringLength(str)
);
nsDependentJSString value;
if (!value.init(aCtx, str))
return nsnull;
return new TextVariant(value);
}

View File

@ -224,11 +224,11 @@ StatementJSHelper::GetProperty(nsIXPConnectWrappedNative *aWrapper,
static_cast<mozIStorageStatement *>(aWrapper->Native())
);
JSString *str = JSID_TO_STRING(aId);
if (::JS_MatchStringAndAscii(str, "row"))
JSFlatString *str = JSID_TO_FLAT_STRING(aId);
if (::JS_FlatStringEqualsAscii(str, "row"))
return getRow(stmt, aCtx, aScopeObj, _result);
if (::JS_MatchStringAndAscii(str, "params"))
if (::JS_FlatStringEqualsAscii(str, "params"))
return getParams(stmt, aCtx, aScopeObj, _result);
return NS_OK;
@ -247,7 +247,7 @@ StatementJSHelper::NewResolve(nsIXPConnectWrappedNative *aWrapper,
if (!JSID_IS_STRING(aId))
return NS_OK;
if (::JS_MatchStringAndAscii(JSID_TO_STRING(aId), "step")) {
if (::JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(aId), "step")) {
*_retval = ::JS_DefineFunction(aCtx, aScopeObj, "step", stepFunc,
0, 0) != nsnull;
*_objp = aScopeObj;

View File

@ -95,9 +95,10 @@ StatementParams::SetProperty(nsIXPConnectWrappedNative *aWrapper,
}
else if (JSID_IS_STRING(aId)) {
JSString *str = JSID_TO_STRING(aId);
NS_ConvertUTF16toUTF8 name(reinterpret_cast<const PRUnichar *>
(::JS_GetStringChars(str)),
::JS_GetStringLength(str));
size_t length;
const jschar *chars = JS_GetStringCharsAndLength(aCtx, str, &length);
NS_ENSURE_TRUE(chars, NS_ERROR_UNEXPECTED);
NS_ConvertUTF16toUTF8 name(chars, length);
// check to see if there's a parameter with this name
nsCOMPtr<nsIVariant> variant(convertJSValToVariant(aCtx, *_vp));
@ -211,8 +212,9 @@ StatementParams::NewResolve(nsIXPConnectWrappedNative *aWrapper,
}
else if (JSID_IS_STRING(aId)) {
JSString *str = JSID_TO_STRING(aId);
jschar *nameChars = ::JS_GetStringChars(str);
size_t nameLength = ::JS_GetStringLength(str);
size_t nameLength;
const jschar *nameChars = JS_GetStringCharsAndLength(aCtx, str, &nameLength);
NS_ENSURE_TRUE(nameChars, NS_ERROR_UNEXPECTED);
// Check to see if there's a parameter with this name, and if not, let
// the rest of the prototype chain be checked.

View File

@ -194,6 +194,7 @@ include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(topsrcdir)/dom/ipc \
-I$(topsrcdir)/toolkit/crashreporter \
-I$(topsrcdir)/dom/base \
$(NULL)
ifdef BUILD_STATIC_LIBS

View File

@ -70,6 +70,7 @@
#include "nsExceptionHandler.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsJSUtils.h"
#include "nsWidgetsCID.h"
#include "nsXREDirProvider.h"
@ -677,8 +678,9 @@ XRE_SendTestShellCommand(JSContext* aCx,
TestShellParent* tsp = GetOrCreateTestShellParent();
NS_ENSURE_TRUE(tsp, false);
nsDependentString command((PRUnichar*)JS_GetStringChars(aCommand),
JS_GetStringLength(aCommand));
nsDependentJSString command;
NS_ENSURE_TRUE(command.init(aCx, aCommand), NS_ERROR_FAILURE);
if (!aCallback) {
return tsp->SendExecuteCommand(command);
}