--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -109,26 +109,26 @@ PRBool nsScriptSecurityManager::sStrictF
///////////////////////////
// Convenience Functions //
///////////////////////////
// Result of this function should not be freed.
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;
if (!JS_IdToValue(cx, id, &idval))
return nsnull;
JSString *str = JS_ValueToString(cx, idval);
if(!str)
return nsnull;
- return reinterpret_cast<PRUnichar*>(JS_GetStringChars(str));
+ return JS_GetStringCharsZ(cx, str);
}
class nsAutoInPrincipalDomainOriginSetter {
public:
nsAutoInPrincipalDomainOriginSetter() {
++sInPrincipalDomainOrigin;
}
~nsAutoInPrincipalDomainOriginSetter() {
--- a/caps/src/nsSecurityManagerFactory.cpp
+++ b/caps/src/nsSecurityManagerFactory.cpp
@@ -90,33 +90,35 @@ getBytesArgument(JSContext *cx, JSObject
JSString *str = getStringArgument(cx, obj, argNum, argc, argv);
return str && bytes->encode(cx, str);
}
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;
}
/*
* We don't want to use JS_ValueToString because we want to be able
* 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;
- }
- PRUnichar *data = (PRUnichar*)JS_GetStringChars(str);
+ const PRUnichar *data = JS_GetStringCharsZ(cx, str);
+ if (!data)
+ return;
+
CopyUTF16toUTF8(data, aRetval);
}
static JSBool
netscape_security_isPrivilegeEnabled(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -203,17 +203,21 @@ nsFrameMessageManager::GetParamsForMessa
PRUint32 argc;
jsval* argv = nsnull;
ncc->GetArgc(&argc);
ncc->GetArgvPtr(&argv);
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) {
jsval v = argv[1];
if (JS_TryJSON(ctx, &v)) {
JS_Stringify(ctx, &v, nsnull, JSVAL_NULL, JSONCreator, &aJSON);
}
}
--- a/content/base/src/nsWebSocket.cpp
+++ b/content/base/src/nsWebSocket.cpp
@@ -2935,27 +2935,37 @@ nsWebSocket::Initialize(nsISupports* aOw
}
JSAutoRequest ar(aContext);
JSString* jsstr = JS_ValueToString(aContext, aArgv[0]);
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;
}
}
nsCOMPtr<nsPIDOMWindow> ownerWindow = do_QueryInterface(aOwner);
NS_ENSURE_STATE(ownerWindow);
--- a/content/events/src/nsEventListenerService.cpp
+++ b/content/events/src/nsEventListenerService.cpp
@@ -135,17 +135,20 @@ nsEventListenerInfo::ToSource(nsAString&
if (cx && NS_SUCCEEDED(stack->Push(cx))) {
{
// Extra block to finish the auto request before calling pop
JSAutoRequest ar(cx);
jsval v = JSVAL_NULL;
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);
+ }
}
}
}
stack->Pop(&cx);
}
}
return NS_OK;
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -135,17 +135,20 @@ nsHTMLAudioElement::Initialize(nsISuppor
return NS_OK;
}
// The only (optional) argument is the url of the audio
JSString* jsstr = JS_ValueToString(aContext, argv[0]);
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;
// We have been specified with a src URL. Begin a load.
QueueSelectResourceTask();
return NS_OK;
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -41,16 +41,17 @@
#include "nsNetUtil.h"
#include "prmem.h"
#include "nsDOMFile.h"
#include "CheckedInt.h"
#include "nsIScriptSecurityManager.h"
#include "nsIXPConnect.h"
#include "jsapi.h"
+#include "nsJSUtils.h"
#include "nsFrameManager.h"
#include "nsDisplayList.h"
#include "ImageLayers.h"
#include "BasicLayers.h"
#include "imgIEncoder.h"
#include "nsIWritablePropertyBag2.h"
@@ -497,28 +498,37 @@ nsHTMLCanvasElement::GetContext(const ns
jsval propname, propval;
if (!JS_IdToValue(cx, propid, &propname) ||
!JS_GetPropertyById(cx, opts, propid, &propval))
{
continue;
}
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);
} else if (JSVAL_IS_INT(propval)) {
newProps->SetPropertyAsInt32(pstr, JSVAL_TO_INT(propval));
} 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);
}
}
}
contextProps = newProps;
}
rv = UpdateContext(contextProps);
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -407,36 +407,44 @@ nsHTMLOptionElement::Initialize(nsISuppo
// Create a new text node and append it to the option
nsCOMPtr<nsIContent> textContent;
result = NS_NewTextNode(getter_AddRefs(textContent),
mNodeInfo->NodeInfoManager());
if (NS_FAILED(result)) {
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)) {
return result;
}
if (argc > 1) {
// The second (optional) parameter is the value of the option
jsstr = JS_ValueToString(aContext, argv[1]);
if (!jsstr) {
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);
if (NS_FAILED(result)) {
return result;
}
if (argc > 2) {
--- a/content/xslt/src/xslt/Makefile.in
+++ b/content/xslt/src/xslt/Makefile.in
@@ -84,16 +84,21 @@ CPPSRCS += txHTMLOutput.cpp \
txXMLOutput.cpp
else
CPPSRCS += txMozillaStylesheetCompiler.cpp \
txMozillaTextOutput.cpp \
txMozillaXMLOutput.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
EXTRA_COMPONENTS = \
txEXSLTRegExFunctions.js \
txEXSLTRegExFunctions.manifest \
$(NULL)
--- a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
+++ b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
@@ -62,16 +62,17 @@
#include "txUnknownHandler.h"
#include "txXSLTProcessor.h"
#include "nsIPrincipal.h"
#include "nsThreadUtils.h"
#include "jsapi.h"
#include "txExprParser.h"
#include "nsIErrorService.h"
#include "nsIScriptSecurityManager.h"
+#include "nsJSUtils.h"
using namespace mozilla::dom;
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
/**
* Output Handler Factories
*/
@@ -1460,20 +1461,18 @@ txVariable::Convert(nsIVariant *aValue,
JSObject *jsobj;
rv = holder->GetJSObject(&jsobj);
NS_ENSURE_SUCCESS(rv, rv);
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) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(*aResult);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -5059,28 +5059,27 @@ nsWindowSH::GlobalScopePolluterNewResolv
document->GetCompatibilityMode() != eCompatibility_NavQuirks) {
// If we don't have a document, or if the document is not in
// quirks mode, return early.
return JS_TRUE;
}
JSObject *proto = ::JS_GetPrototype(cx, obj);
- JSString *jsstr = JSID_TO_STRING(id);
JSBool hasProp;
if (!proto || !::JS_HasPropertyById(cx, proto, id, &hasProp) ||
hasProp) {
// No prototype, or the property exists on the prototype. Do
// nothing.
return JS_TRUE;
}
- nsDependentJSString str(jsstr);
+ nsDependentJSString str(id);
nsCOMPtr<nsISupports> result;
nsWrapperCache *cache;
{
Element *element = document->GetElementById(str);
result = element;
cache = element;
}
@@ -5409,17 +5408,20 @@ nsWindowSH::SetProperty(nsIXPConnectWrap
nsresult rv = window->GetLocation(getter_AddRefs(location));
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && location, rv);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), PR_TRUE,
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;
}
return nsEventReceiverSH::SetProperty(wrapper, cx, obj, id, vp, _retval);
}
NS_IMETHODIMP
@@ -6264,24 +6266,24 @@ ResolvePrototype(nsIXPConnect *aXPConnec
return NS_OK;
}
// 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;
nameSpaceManager->LookupName(name, &name_struct, &class_name);
if (!name_struct) {
return NS_OK;
@@ -6481,20 +6483,18 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
}
rv = WrapNative(cx, scope, native, PR_TRUE, &prop_val,
getter_AddRefs(holder));
}
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;
return ok ? NS_OK : NS_ERROR_FAILURE;
}
if (name_struct->mType == nsGlobalNameStruct::eTypeDynamicNameSet) {
nsCOMPtr<nsIScriptExternalNameSet> nameset =
@@ -6643,32 +6643,30 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
return NS_OK;
}
// Hmm, we do an awful lot of QIs here; maybe we should add a
// 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()));
PRInt32 count = 0;
if (dsn) {
dsn->GetChildCount(&count);
}
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,
getter_AddRefs(child));
nsCOMPtr<nsIDOMWindow> child_win(do_GetInterface(child));
if (child_win) {
@@ -6707,17 +6705,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
if (!(flags & JSRESOLVE_ASSIGNING)) {
JSAutoRequest ar(cx);
// Call GlobalResolve() after we call FindChildWithName() so
// that named child frames will override external properties
// 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) {
// GlobalResolve() resolved something, so we're done here.
*objp = obj;
return NS_OK;
}
@@ -8377,17 +8375,20 @@ nsDocumentSH::SetProperty(nsIXPConnectWr
NS_ENSURE_SUCCESS(rv, rv);
if (location) {
JSAutoRequest ar(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;
rv = WrapNative(cx, JS_GetGlobalForScopeChain(cx), location,
&NS_GET_IID(nsIDOMLocation), PR_TRUE, vp,
getter_AddRefs(holder));
return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
}
@@ -8466,17 +8467,20 @@ ResolveImpl(JSContext *cx, nsIXPConnectW
static_cast<nsHTMLDocument*>(static_cast<nsINode*>(wrapper->Native()));
// 'id' is not always a string, it can be a number since document.1
// should map to <input name="1">. Thus we can't use
// JSVAL_TO_STRING() here.
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
JSBool
nsHTMLDocumentSH::DocumentOpen(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
@@ -8504,18 +8508,23 @@ nsHTMLDocumentSH::DocumentOpen(JSContext
nsCAutoString contentType("text/html");
if (argc > 0) {
JSString* jsstr = JS_ValueToString(cx, argv[0]);
if (!jsstr) {
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);
if (!actualType.EqualsLiteral("text/html") &&
!type.EqualsLiteral("replace")) {
contentType = "text/plain";
}
}
@@ -8523,19 +8532,23 @@ nsHTMLDocumentSH::DocumentOpen(JSContext
PRBool replace = PR_FALSE;
if (argc > 1) {
JSString* jsstr = JS_ValueToString(cx, argv[1]);
if (!jsstr) {
nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_OUT_OF_MEMORY);
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;
nsresult rv = doc->Open(contentType, replace, getter_AddRefs(retval));
if (NS_FAILED(rv)) {
nsDOMClassInfo::ThrowJSException(cx, rv);
return JS_FALSE;
@@ -8844,18 +8857,23 @@ nsHTMLDocumentSH::CallToGetPropMapper(JS
return JS_FALSE;
} else {
// In other cases (i.e. document.all("foo")), self is passed as
// the callee
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);
}
static inline JSObject *
GetDocumentAllHelper(JSContext *cx, JSObject *obj)
{
while (obj && JS_GET_CLASS(cx, obj) != &sHTMLDocumentAllHelperClass) {
obj = ::JS_GetPrototype(cx, obj);
@@ -8965,34 +8983,32 @@ nsHTMLDocumentSH::DocumentAllHelperNewRe
JSBool
nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj,
jsid id, uintN flags,
JSObject **objp)
{
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;
}
JSBool found;
if (!::JS_HasPropertyById(cx, proto, id, &found)) {
return JS_FALSE;
}
if (found) {
return JS_TRUE;
}
nsRefPtr<nsContentList> tags =
- doc->GetElementsByTagName(nsDependentJSString(str));
+ doc->GetElementsByTagName(nsDependentJSString(id));
if (tags) {
jsval v;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
nsresult rv = nsDOMClassInfo::WrapNative(cx, JS_GetGlobalForScopeChain(cx),
static_cast<nsINodeList*>(tags),
tags, PR_TRUE, &v,
getter_AddRefs(holder));
@@ -9154,21 +9170,21 @@ nsHTMLDocumentSH::GetProperty(nsIXPConne
return nsDocumentSH::GetProperty(wrapper, cx, obj, id, vp, _retval);
}
// HTMLFormElement helper
// 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
*aCache = nsnull;
if (!*aResult) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aForm));
nsCOMPtr<nsIDOMHTMLFormElement> form_element(do_QueryInterface(aForm));
@@ -9192,18 +9208,17 @@ nsHTMLFormElementSH::NewResolve(nsIXPCon
{
// For native wrappers, do not resolve random names on form
if ((!(JSRESOLVE_ASSIGNING & flags)) && JSID_IS_STRING(id) &&
!ObjectIsNativeWrapper(cx, obj)) {
nsCOMPtr<nsIForm> form(do_QueryWrappedNative(wrapper, obj));
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);
*_retval = ::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, nsnull,
nsnull, JSPROP_ENUMERATE);
*objp = obj;
@@ -9223,18 +9238,17 @@ nsHTMLFormElementSH::GetProperty(nsIXPCo
nsCOMPtr<nsIForm> form(do_QueryWrappedNative(wrapper, obj));
if (JSID_IS_STRING(id)) {
// For native wrappers, do not get random names on form
if (!ObjectIsNativeWrapper(cx, obj)) {
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
// elements
nsresult rv = WrapNative(cx, obj, result, cache, PR_TRUE, vp);
return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
}
}
@@ -10168,21 +10182,24 @@ nsStorageSH::NewResolve(nsIXPConnectWrap
// check if the key exists in the storage object.
nsCOMPtr<nsIDOMStorageObsolete> storage(do_QueryWrappedNative(wrapper));
JSString *jsstr = IdToString(cx, id);
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) {
if (!::JS_DefinePropertyById(cx, realObj, id, JSVAL_VOID, nsnull, nsnull,
JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
@@ -10207,21 +10224,26 @@ nsStorageSH::SetProperty(nsIXPConnectWra
jsval *vp, PRBool *_retval)
{
nsCOMPtr<nsIDOMStorageObsolete> storage(do_QueryWrappedNative(wrapper));
NS_ENSURE_TRUE(storage, NS_ERROR_UNEXPECTED);
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;
}
return rv;
}
NS_IMETHODIMP
@@ -10230,17 +10252,20 @@ nsStorageSH::DelProperty(nsIXPConnectWra
jsval *vp, PRBool *_retval)
{
nsCOMPtr<nsIDOMStorageObsolete> storage(do_QueryWrappedNative(wrapper));
NS_ENSURE_TRUE(storage, NS_ERROR_UNEXPECTED);
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;
}
return rv;
}
@@ -10329,20 +10354,23 @@ nsStorage2SH::NewResolve(nsIXPConnectWra
return NS_OK;
}
// We're resolving property that doesn't exist on the prototype,
// check if the key exists in the storage object.
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)) {
if (!::JS_DefinePropertyById(cx, realObj, id, JSVAL_VOID, nsnull,
nsnull, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
@@ -10401,21 +10429,26 @@ nsStorage2SH::SetProperty(nsIXPConnectWr
jsval *vp, PRBool *_retval)
{
nsCOMPtr<nsIDOMStorage> storage(do_QueryWrappedNative(wrapper));
NS_ENSURE_TRUE(storage, NS_ERROR_UNEXPECTED);
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;
}
return rv;
}
NS_IMETHODIMP
@@ -10424,17 +10457,20 @@ nsStorage2SH::DelProperty(nsIXPConnectWr
jsval *vp, PRBool *_retval)
{
nsCOMPtr<nsIDOMStorage> storage(do_QueryWrappedNative(wrapper));
NS_ENSURE_TRUE(storage, NS_ERROR_UNEXPECTED);
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;
}
return rv;
}
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -449,17 +449,17 @@ protected:
}
static PRBool ReallyIsEventName(jsid id, jschar aFirstChar);
static inline PRBool IsEventName(jsid id)
{
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]);
}
return PR_FALSE;
}
@@ -514,18 +514,17 @@ protected:
{
}
virtual ~nsWindowSH()
{
}
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,
JSObject *globalObj, JSObject **parentObj);
#ifdef DEBUG
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj)
{
@@ -1032,17 +1031,17 @@ protected:
nsHTMLFormElementSH(nsDOMClassInfoData* aData) : nsElementSH(aData)
{
}
virtual ~nsHTMLFormElementSH()
{
}
- static nsresult FindNamedItem(nsIForm *aForm, JSString *str,
+ static nsresult FindNamedItem(nsIForm *aForm, jsid id,
nsISupports **aResult, nsWrapperCache **aCache);
public:
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, PRBool *_retval);
NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, jsval *vp,
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -719,18 +719,23 @@ LocaleToUnicode(JSContext *cx, char *src
return JS_TRUE;
}
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) {
return JS_FALSE;
}
*rval = STRING_TO_JSVAL(ucstr);
@@ -774,21 +779,24 @@ LocaleCompare(JSContext *cx, JSString *s
if (NS_FAILED(rv)) {
nsDOMClassInfo::ThrowJSException(cx, rv);
return JS_FALSE;
}
}
+ 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);
return JS_FALSE;
}
*rval = INT_TO_JSVAL(result);
@@ -1586,37 +1594,46 @@ JSValueToAString(JSContext *cx, jsval va
*isUndefined = JSVAL_IS_VOID(val);
}
if (!result) {
return NS_OK;
}
JSString* jsstring = ::JS_ValueToString(cx, val);
- if (jsstring) {
- result->Assign(reinterpret_cast<const PRUnichar*>
- (::JS_GetStringChars(jsstring)),
- ::JS_GetStringLength(jsstring));
- } else {
- result->Truncate();
-
- // 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.
-
- if (isUndefined) {
- *isUndefined = PR_TRUE;
- }
-
- if (!::JS_IsExceptionPending(cx)) {
- // JS_ValueToString() returned null w/o an exception
- // pending. That means we're OOM.
-
- return NS_ERROR_OUT_OF_MEMORY;
- }
+ if (!jsstring) {
+ goto error;
+ }
+
+ size_t length;
+ const jschar *chars;
+ chars = ::JS_GetStringCharsAndLength(cx, jsstring, &length);
+ if (!chars) {
+ goto error;
+ }
+
+ result->Assign(chars, length);
+ return NS_OK;
+
+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.
+
+ 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;
}
nsIScriptObjectPrincipal*
nsJSContext::GetObjectPrincipal()
{
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -104,17 +104,17 @@ private:
// filename, line number and JS language version string of the
// caller of setTimeout()
nsCString mFileName;
PRUint32 mLineNo;
PRUint32 mVersion;
nsCOMPtr<nsIArray> mArgv;
// The JS expression to evaluate or function to call, if !mExpr
- JSString *mExpr;
+ JSFlatString *mExpr;
JSObject *mFunObj;
};
// nsJSScriptTimeoutHandler
// QueryInterface implementation for nsJSScriptTimeoutHandler
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSScriptTimeoutHandler)
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsJSScriptTimeoutHandler)
@@ -129,20 +129,20 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
foo.Append(tmp->mFileName);
foo.AppendLiteral(":");
foo.AppendInt(tmp->mLineNo);
foo.AppendLiteral("]");
}
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;
foo.AppendLiteral("]");
}
}
}
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(),
@@ -227,17 +227,17 @@ nsJSScriptTimeoutHandler::Init(nsGlobalW
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 argc;
jsval *argv = nsnull;
ncc->GetArgc(&argc);
ncc->GetArgvPtr(&argv);
- JSString *expr = nsnull;
+ JSFlatString *expr = nsnull;
JSObject *funobj = nsnull;
int32 interval = 0;
JSAutoRequest ar(cx);
if (argc < 1) {
::JS_ReportError(cx, "Function %s requires at least 2 parameter",
*aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
@@ -259,20 +259,27 @@ nsJSScriptTimeoutHandler::Init(nsGlobalW
switch (::JS_TypeOfValue(cx, argv[0])) {
case JSTYPE_FUNCTION:
funobj = JSVAL_TO_OBJECT(argv[0]);
break;
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:
::JS_ReportError(cx, "useless %s call (missing quotes around argument?)",
*aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
// Return an error that nsGlobalWindow can recognize and turn into NS_OK.
return NS_ERROR_DOM_TYPE_ERR;
@@ -365,18 +372,17 @@ void nsJSScriptTimeoutHandler::SetLatene
NS_ERROR("How can our argv not handle this?");
}
}
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,
PRBool *aIsInterval,
PRInt32 *aInterval,
nsIScriptTimeoutHandler **aRet)
{
*aRet = nsnull;
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -70,31 +70,52 @@ public:
static nsIScriptContext *GetDynamicScriptContext(JSContext *aContext);
};
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(JS_GetInternedStringChars(JSID_TO_STRING(id)),
+ JS_GetStringLength(JSID_TO_STRING(id)))
{
}
- explicit nsDependentJSString(jsid id)
- : nsDependentString((PRUnichar *)::JS_GetStringChars(JSID_TO_STRING(id)),
- ::JS_GetStringLength(JSID_TO_STRING(id)))
+ /**
+ * 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()
{
}
- explicit nsDependentJSString(JSString *str)
- : nsDependentString((PRUnichar *)::JS_GetStringChars(str), ::JS_GetStringLength(str))
+ 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()
{
}
};
#endif /* nsJSUtils_h__ */
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -420,17 +420,17 @@ IDBCursor::Continue(const jsval &aKey,
}
if (mContinueCalled) {
// XXX Update the spec for precise behavior here.
return NS_OK;
}
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()) {
if (aOptionalArgCount) {
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
}
else {
key = Key::UNSETKEY;
@@ -499,17 +499,17 @@ IDBCursor::Update(const jsval& aValue,
ok = JS_DefineUCProperty(aCx, JSVAL_TO_OBJECT(clone.jsval_value()),
keyPathChars, keyPathLen, prop.jsval_value(), nsnull,
nsnull, JSPROP_ENUMERATE);
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
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) {
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
}
}
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -352,17 +352,17 @@ GetKeyFromObject(JSContext* aCx,
const jschar* keyPathChars = reinterpret_cast<const jschar*>(aKeyPath.get());
const size_t keyPathLen = aKeyPath.Length();
jsval key;
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;
}
inline
already_AddRefed<IDBRequest>
GenerateRequest(IDBObjectStore* aObjectStore)
@@ -437,26 +437,31 @@ IDBObjectStore::GetKeyFromVariant(nsIVar
}
return NS_OK;
}
// static
nsresult
IDBObjectStore::GetKeyFromJSVal(jsval aKeyVal,
+ JSContext* aCx,
Key& aKey)
{
if (JSVAL_IS_VOID(aKeyVal)) {
aKey = Key::UNSETKEY;
}
else if (JSVAL_IS_NULL(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);
}
else if (JSVAL_IS_DOUBLE(aKeyVal)) {
aKey = JSVAL_TO_DOUBLE(aKeyVal);
}
else {
@@ -581,17 +586,22 @@ IDBObjectStore::GetKeyPathValueFromJSON(
reinterpret_cast<const jschar*>(aKeyPath.BeginReading());
const size_t keyPathLen = aKeyPath.Length();
js::AutoValueRooter value(*aCx);
JSBool ok = JS_GetUCProperty(*aCx, obj, keyPathChars, keyPathLen,
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.
aValue = Key::UNSETKEY;
}
return NS_OK;
}
@@ -622,17 +632,22 @@ IDBObjectStore::GetIndexUpdateInfo(Objec
const size_t keyPathLen = indexInfo.keyPath.Length();
jsval keyPathValue;
JSBool ok = JS_GetUCProperty(aCx, cloneObj, keyPathChars, keyPathLen,
&keyPathValue);
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;
}
IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
updateInfo->info = indexInfo;
updateInfo->value = value;
@@ -789,17 +804,17 @@ IDBObjectStore::GetAddInfo(JSContext* aC
Key& aKey,
nsTArray<IndexUpdateInfo>& aUpdateInfoArray)
{
nsresult rv;
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 {
// Inline keys live on the object. Make sure it is an object.
if (JSVAL_IS_PRIMITIVE(aValue)) {
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
}
--- a/dom/indexedDB/IDBObjectStore.h
+++ b/dom/indexedDB/IDBObjectStore.h
@@ -73,16 +73,17 @@ public:
const ObjectStoreInfo* aInfo);
static nsresult
GetKeyFromVariant(nsIVariant* aKeyVariant,
Key& aKey);
static nsresult
GetKeyFromJSVal(jsval aKeyVal,
+ JSContext* aCx,
Key& aKey);
static nsresult
GetJSValFromKey(const Key& aKey,
JSContext* aCx,
jsval* aKeyVal);
static nsresult
--- a/dom/src/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/src/jsurl/nsJSProtocolHandler.cpp
@@ -330,17 +330,24 @@ nsresult nsJSThunk::EvaluateScript(nsICh
JS_ReportPendingException(cx);
isUndefined = PR_TRUE;
} else {
isUndefined = rval == JSVAL_VOID;
}
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);
} else {
// No need to use the sandbox, evaluate the script directly in
// the given scope.
rv = scriptContext->EvaluateString(NS_ConvertUTF8toUTF16(script),
globalJSObject, // obj
--- a/dom/src/threads/nsDOMWorker.cpp
+++ b/dom/src/threads/nsDOMWorker.cpp
@@ -137,19 +137,21 @@ nsDOMWorkerFunctions::Dump(JSContext* aC
{
JS_SET_RVAL(cx, aVp, JSVAL_VOID);
if (!nsGlobalWindow::DOMWindowDumpEnabled()) {
return JS_TRUE;
}
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;
}
JSBool
nsDOMWorkerFunctions::MakeTimeout(JSContext* aCx,
uintN aArgc,
jsval* aVp,
@@ -263,17 +265,22 @@ nsDOMWorkerFunctions::LoadScripts(JSCont
if (!str) {
JS_ReportError(aCx, "Couldn't convert argument %d to a string", index);
return JS_FALSE;
}
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 =
new nsDOMWorkerScriptLoader(worker);
if (!loader) {
JS_ReportOutOfMemory(aCx);
return JS_FALSE;
}
@@ -502,18 +509,17 @@ nsDOMWorkerFunctions::CTypesLazyGetter(J
JSObject* aObj,
jsid aId,
jsval* aVp)
{
#ifdef DEBUG
{
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));
NS_ASSERTION(worker, "This should be set by the DOM thread service!");
NS_ASSERTION(worker->IsPrivileged(), "This shouldn't be possible!");
if (worker->IsCanceled()) {
return JS_FALSE;
@@ -669,24 +675,24 @@ nsDOMWorkerScope::AddProperty(nsIXPConne
JSObject* funObj;
if (!(JSID_IS_STRING(aId) &&
JSVAL_IS_OBJECT(*aVp) &&
(funObj = JSVAL_TO_OBJECT(*aVp)) &&
JS_ObjectIsFunction(aCx, funObj))) {
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 {
// Some other function, we don't need to do anything special after all.
return NS_OK;
}
// Wrap the function as an nsIDOMEventListener.
@@ -1297,17 +1303,20 @@ nsDOMWorker::InitializeInternal(nsIScrip
jsval* aArgv)
{
NS_ENSURE_TRUE(aArgc, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
NS_ENSURE_ARG_POINTER(aArgv);
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");
NS_ENSURE_TRUE(mLock, NS_ERROR_OUT_OF_MEMORY);
NS_ASSERTION(!mGlobal, "Already got a global?!");
nsCOMPtr<nsIXPConnectJSObjectHolder> thisWrapped;
--- a/dom/src/threads/nsDOMWorkerTimeout.cpp
+++ b/dom/src/threads/nsDOMWorkerTimeout.cpp
@@ -191,21 +191,20 @@ nsDOMWorkerTimeout::ExpressionCallback::
NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
JSPrincipals* principal = nsDOMWorkerSecurityManager::WorkerPrincipal();
NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
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,
mFileName.get(),
mLineNumber, &rval);
if (!success) {
return NS_ERROR_FAILURE;
}
--- a/extensions/jssh/nsJSSh.cpp
+++ b/extensions/jssh/nsJSSh.cpp
@@ -273,30 +273,33 @@ static JSBool
SetProtocol(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
if (argc!=1) return JS_FALSE;
nsJSSh* shell;
if (!GetJSShGlobal(cx, obj, &shell)) return JS_FALSE;
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;
}
else return JS_FALSE;
return JS_TRUE;
}
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -1248,20 +1248,23 @@ XPCShellEnvironment::EvaluateString(cons
aResult->Truncate();
}
jsval result;
JSBool ok = JS_ExecuteScript(mCx, global, script, &result);
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);
}
}
}
JS_DestroyScript(mCx, script);
return true;
}
--- a/js/ipc/Makefile.in
+++ b/js/ipc/Makefile.in
@@ -58,13 +58,18 @@ EXPORTS_mozilla/jsipc = \
ObjectWrapperChild.h \
$(NULL)
CPPSRCS = \
ObjectWrapperParent.cpp \
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
DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
--- a/js/ipc/ObjectWrapperChild.cpp
+++ b/js/ipc/ObjectWrapperChild.cpp
@@ -45,16 +45,17 @@
#include "mozilla/jsipc/ObjectWrapperChild.h"
#include "mozilla/jsipc/CPOWTypes.h"
#include "jsapi.h"
#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "nsContentUtils.h"
#include "nsIJSContextStack.h"
+#include "nsJSUtils.h"
using namespace mozilla::jsipc;
using namespace js;
namespace {
class AutoContextPusher {
@@ -183,18 +184,22 @@ ObjectWrapperChild::jsval_to_JSVariant(J
if (from != JSVAL_NULL)
return false;
// fall through
case JSTYPE_FUNCTION:
// fall through
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))
*to = JSVAL_TO_INT(from);
else if (JSVAL_IS_DOUBLE(from))
*to = JSVAL_TO_DOUBLE(from);
else return false;
return true;
@@ -277,20 +282,20 @@ ObjectWrapperChild::Manager()
{
PContextWrapperChild* pcwc = PObjectWrapperChild::Manager();
return static_cast<ContextWrapperChild*>(pcwc);
}
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;
}
static bool
jsid_from_nsString(JSContext* cx, const nsString& from, jsid* to)
{
--- a/js/ipc/ObjectWrapperParent.cpp
+++ b/js/ipc/ObjectWrapperParent.cpp
@@ -37,16 +37,17 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "mozilla/jsipc/ObjectWrapperParent.h"
#include "mozilla/jsipc/ContextWrapperParent.h"
#include "mozilla/jsipc/CPOWTypes.h"
#include "mozilla/unused.h"
+#include "nsJSUtils.h"
#include "jsobj.h"
#include "jsfun.h"
#include "jsutil.h"
using namespace mozilla::jsipc;
namespace {
@@ -260,18 +261,22 @@ ObjectWrapperParent::jsval_to_JSVariant(
{
PObjectWrapperParent* powp;
if (!JSObject_to_PObjectWrapperParent(cx, JSVAL_TO_OBJECT(from), &powp))
return with_error(cx, false, "Cannot pass parent-created object to child");
*to = powp;
}
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))
*to = JSVAL_TO_INT(from);
else if (JSVAL_IS_DOUBLE(from))
*to = JSVAL_TO_DOUBLE(from);
else return false;
return true;
@@ -374,20 +379,22 @@ jsid_from_nsString(JSContext* cx, const
return false;
return JS_ValueToId(cx, STRING_TO_JSVAL(str), to);
}
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;
}
/*static*/ JSBool
ObjectWrapperParent::CPOW_AddProperty(JSContext *cx, JSObject *obj, jsid id,
jsval *vp)
--- a/js/jetpack/JetpackActorCommon.cpp
+++ b/js/jetpack/JetpackActorCommon.cpp
@@ -44,16 +44,18 @@
#include "jshashtable.h"
#include "mozilla/jetpack/JetpackActorCommon.h"
#include "mozilla/jetpack/PJetpack.h"
#include "mozilla/jetpack/PHandleParent.h"
#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;
using mozilla::jetpack::PHandleChild;
using mozilla::jetpack::HandleChild;
using mozilla::jetpack::KeyValue;
using mozilla::jetpack::PrimVariant;
using mozilla::jetpack::CompVariant;
@@ -133,18 +135,22 @@ JetpackActorCommon::jsval_to_PrimVariant
if (hc) {
*to = hc;
return true;
}
return false;
}
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))
*to = JSVAL_TO_INT(from);
else if (JSVAL_IS_DOUBLE(from))
*to = JSVAL_TO_DOUBLE(from);
else
@@ -218,18 +224,20 @@ JetpackActorCommon::jsval_to_CompVariant
JSString* idStr = JS_ValueToString(cx, val);
if (!idStr)
return false;
if (!JS_GetPropertyById(cx, obj, ida[i], &val))
return false;
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);
}
}
InfallibleTArray<KeyValue> outKvs;
outKvs.SwapElements(kvs);
*to = outKvs;
--- a/js/jetpack/JetpackChild.cpp
+++ b/js/jetpack/JetpackChild.cpp
@@ -91,17 +91,17 @@ JetpackChild::sGlobalClass = {
JSCLASS_NO_OPTIONAL_MEMBERS
};
#ifdef BUILD_CTYPES
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");
return NULL;
}
char* result = static_cast<char*>(JS_malloc(cx, native.Length() + 1));
if (!result)
@@ -246,18 +246,22 @@ MessageCommon(JSContext* cx, uintN argc,
jsval* argv = JS_ARGV(cx, vp);
JSString* msgNameStr = JS_ValueToString(cx, argv[0]);
if (!msgNameStr) {
JS_ReportError(cx, "Could not convert value to string");
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();
if (!result->data.SetCapacity(argc)) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
@@ -350,18 +354,22 @@ ReceiverCommon(JSContext* cx, uintN argc
JSString* str = JS_ValueToString(cx, argv[0]);
if (!str) {
JS_ReportError(cx, "%s expects a stringifiable value as its first argument",
methodName);
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;
if (JS_TypeOfValue(cx, argv[1]) != JSTYPE_FUNCTION) {
JS_ReportError(cx, "%s expects a function as its second argument",
methodName);
return JS_FALSE;
@@ -492,19 +500,23 @@ JetpackChild::EvalInSandbox(JSContext* c
if (&sGlobalClass != JS_GetClass(cx, obj) ||
obj == JS_GetGlobalObject(cx)) {
JS_ReportError(cx, "The first argument to evalInSandbox must be a global object created using createSandbox.");
JS_ASSERT(JS_FALSE);
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;
/* static */ void
JetpackChild::ReportError(JSContext* cx, const char* message,
JSErrorReport* report)
{
--- a/js/jetpack/Makefile.in
+++ b/js/jetpack/Makefile.in
@@ -69,15 +69,20 @@ CPPSRCS = \
JetpackParent.cpp \
JetpackChild.cpp \
JetpackProcessChild.cpp \
JetpackProcessParent.cpp \
JetpackService.cpp \
JetpackActorCommon.cpp \
$(NULL)
+# For nsDependentJSString
+LOCAL_INCLUDES += \
+ -I$(topsrcdir)/dom/base \
+ $(NULL)
+
ifdef ENABLE_TESTS
TOOL_DIRS += tests
endif
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
--- a/js/jsd/jsd_scpt.c
+++ b/js/jsd/jsd_scpt.c
@@ -209,17 +209,18 @@ static void
extent = jsd_GetScriptLineExtent(jsdc, jsdscript);
n = size_t(snprintf(Buf, sizeof(Buf), "%sscript=%08X, %s, ",
leadingtext, (unsigned) jsdscript->script,
name ? name : "no URL"));
if (n + 1 < sizeof(Buf)) {
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))
snprintf(Buf + n, sizeof(Buf) - n, ", %d-%d\n", base, base + extent - 1);
}
OutputDebugString( Buf );
}
--- a/js/jsd/jsd_val.c
+++ b/js/jsd/jsd_val.c
@@ -557,27 +557,30 @@ jsd_GetValueProperty(JSDContext* jsdc, J
if(!jsd_IsValueObject(jsdc, jsdval))
return NULL;
/* If we already have the prop, then return it */
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 */
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);
if(!call) {
JS_EndRequest(cx);
return NULL;
}
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -1049,23 +1049,26 @@ jsdScript::CreatePPLineMap()
nargs = JS_GetFunctionArgumentCount(cx, fun);
if (nargs > 12)
return nsnull;
jsstr = JS_DecompileFunctionBody (cx, fun, 4);
if (!jsstr)
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;
} else {
/* Enter a new block so we can leave before the end of this block */
do {
script = JSD_GetJSScript(mCx, mScript);
@@ -1074,19 +1077,22 @@ jsdScript::CreatePPLineMap()
return nsnull;
jsstr = JS_DecompileScript (cx, JSD_GetJSScript(mCx, mScript),
"ppscript", 4);
if (!jsstr)
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;
scriptOwner = PR_TRUE;
baseLine = 1;
}
PRUint32 scriptExtent = JS_GetScriptLineExtent (cx, script);
@@ -1298,18 +1304,17 @@ jsdScript::GetParameterNames(PRUint32* c
nsresult rv = NS_OK;
for (uintN i = 0; i < nargs; ++i) {
JSAtom *atom = JS_LocalNameToAtom(names[i]);
if (!atom) {
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;
break;
}
}
}
JS_ReleaseFunctionLocalNameArray(cx, mark);
@@ -1371,20 +1376,22 @@ jsdScript::GetFunctionSource(nsAString &
JSScript *script = JSD_GetJSScript (mCx, mScript);
if (!ac.enter(cx, script))
return NS_ERROR_FAILURE;
jsstr = JS_DecompileScript (cx, script, "ppscript", 4);
}
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;
}
NS_IMETHODIMP
jsdScript::GetBaseLineNumber(PRUint32 *_rval)
{
*_rval = mBaseLineNumber;
return NS_OK;
@@ -2269,22 +2276,29 @@ jsdValue::GetObjectValue(jsdIObject **_r
return NS_ERROR_FAILURE;
return NS_OK;
}
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();
}
return NS_OK;
}
NS_IMETHODIMP
jsdValue::GetPropertyCount (PRInt32 *_rval)
--- a/js/src/jsapi-tests/testIntString.cpp
+++ b/js/src/jsapi-tests/testIntString.cpp
@@ -7,34 +7,34 @@
BEGIN_TEST(testIntString_bug515273)
{
jsvalRoot v(cx);
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;
}
END_TEST(testIntString_bug515273)
--- a/js/src/jsapi-tests/testLookup.cpp
+++ b/js/src/jsapi-tests/testLookup.cpp
@@ -36,17 +36,20 @@ JSBool
document_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp)
{
// If id is "all", and we're not detecting, resolve document.all=true.
jsvalRoot v(cx);
if (!JS_IdToValue(cx, id, v.addr()))
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;
}
}
*objp = NULL;
return true;
}
--- a/js/src/jsapi-tests/testSameValue.cpp
+++ b/js/src/jsapi-tests/testSameValue.cpp
@@ -11,12 +11,14 @@ BEGIN_TEST(testSameValue)
* NB: passing a double that fits in an integer jsval is API misuse. As a
* matter of defense in depth, however, JS_SameValue should return the
* correct result comparing a positive-zero double to a negative-zero
* double, and this is believed to be the only way to make such a
* comparison possible.
*/
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)
--- a/js/src/jsapi-tests/testTrap.cpp
+++ b/js/src/jsapi-tests/testTrap.cpp
@@ -57,22 +57,22 @@ BEGIN_TEST(testTrap_gc)
static const char trapClosureText[] = "some trap closure";
JSString *trapClosure = JS_NewStringCopyZ(cx, trapClosureText);
CHECK(trapClosure);
JS_SetTrap(cx, script, line2, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
JS_SetTrap(cx, script, line6, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
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()));
CHECK(emptyTrapCallCount == 11);
JS_GC(cx);
- CHECK(JS_MatchStringAndAscii(trapClosure, trapClosureText));
+ CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
return true;
}
END_TEST(testTrap_gc)
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -187,17 +187,18 @@ class JSAPITest
do { \
if (!checkSame(actual, expected, #actual, #expected, __FILE__, __LINE__)) \
return false; \
} while (false)
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);
}
#define CHECK(expr) \
do { \
if (!(expr)) \
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -576,27 +576,29 @@ JS_PUBLIC_API(const char *)
JS_GetTypeName(JSContext *cx, JSType type)
{
if ((uintN)type >= (uintN)JSTYPE_LIMIT)
return NULL;
return JS_TYPE_STR(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;
}
/************************************************************************/
/*
* Has a new runtime ever been created? This flag is used to detect unsafe
* changes to js_CStringsAreUTF8 after a runtime has been created, and to
* ensure that "first checks" on runtime creation are run only once.
@@ -5241,16 +5243,26 @@ JS_NewStringCopyZ(JSContext *cx, const c
JS_PUBLIC_API(JSBool)
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)
{
JSAtom *atom;
CHECK_REQUEST(cx);
atom = js_Atomize(cx, s, strlen(s), ATOM_INTERNED);
if (!atom)
return NULL;
@@ -5293,89 +5305,105 @@ JS_InternUCStringN(JSContext *cx, const
}
JS_PUBLIC_API(JSString *)
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)
{
return str->length();
}
JS_PUBLIC_API(const jschar *)
-JS_GetStringCharsAndLength(JSString *str, size_t *lengthp)
-{
- *lengthp = str->length();
- return str->chars();
+JS_GetStringCharsZ(JSContext *cx, JSString *str)
+{
+ CHECK_REQUEST(cx);
+ assertSameCompartment(cx, str);
+ return str->getCharsZ(cx);
+}
+
+JS_PUBLIC_API(const jschar *)
+JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *plength)
+{
+ CHECK_REQUEST(cx);
+ assertSameCompartment(cx, str);
+ *plength = str->length();
+ return str->getCharsZ(cx);
+}
+
+JS_PUBLIC_API(const jschar *)
+JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *plength)
+{
+ 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_GetStringCharsZ(JSContext *cx, JSString *str)
-{
+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->undepend(cx);
-}
-
-JS_PUBLIC_API(intN)
-JS_CompareStrings(JSString *str1, JSString *str2)
-{
- return js_CompareStrings(str1, str2);
+ 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);
}
JS_PUBLIC_API(JSBool)
JS_FileEscapedString(FILE *fp, JSString *str, char quote)
{
return FileEscapedString(fp, str, quote);
@@ -5401,17 +5429,17 @@ JS_ConcatStrings(JSContext *cx, JSString
CHECK_REQUEST(cx);
return js_ConcatStrings(cx, left, right);
}
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)
JS_MakeStringImmutable(JSContext *cx, JSString *str)
{
CHECK_REQUEST(cx);
return js_MakeStringImmutable(cx, str);
}
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -697,20 +697,20 @@ JS_ValueToBoolean(JSContext *cx, jsval v
extern JS_PUBLIC_API(JSType)
JS_TypeOfValue(JSContext *cx, jsval v);
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);
/************************************************************************/
/*
* Initialization, locking, contexts, and memory allocation.
*
* It is important that the first runtime and first context be created in a
* single-threaded fashion, otherwise the behavior of the library is undefined.
@@ -2932,16 +2932,19 @@ JS_RestoreFrameChain(JSContext *cx, JSSt
*/
extern JS_PUBLIC_API(JSString *)
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);
extern JS_PUBLIC_API(JSString *)
JS_NewUCString(JSContext *cx, jschar *chars, size_t length);
extern JS_PUBLIC_API(JSString *)
JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n);
@@ -2949,46 +2952,116 @@ extern JS_PUBLIC_API(JSString *)
JS_NewUCStringCopyZ(JSContext *cx, const jschar *s);
extern JS_PUBLIC_API(JSString *)
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(JSContext *cx, JSString *str, size_t *length);
+
extern JS_PUBLIC_API(const jschar *)
-JS_GetStringCharsAndLength(JSString *str, size_t *lengthp);
+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
* JS_NewUCString instead.
*/
extern JS_PUBLIC_API(JSString *)
JS_NewGrowableString(JSContext *cx, jschar *chars, size_t length);
--- a/js/src/jsarray.h
+++ b/js/src/jsarray.h
@@ -40,16 +40,17 @@
#ifndef jsarray_h___
#define jsarray_h___
/*
* JS Array interface.
*/
#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;
inline JSObject::EnsureDenseResult
JSObject::ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra)
{
JS_ASSERT(isDenseArray());
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -55,17 +55,17 @@
#define ATOM_PINNED 0x1 /* atom is pinned against GC */
#define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */
#define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */
#define ATOM_TMPSTR 0x8 /* internal, to avoid extra string */
#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 */
static JS_ALWAYS_INLINE jsid
JSID_FROM_BITS(size_t bits)
{
jsid id;
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -315,16 +315,22 @@ struct JSString
inline size_t dependentLength() const {
JS_ASSERT(isDependent());
return length();
}
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);
}
const jschar *nonRopeChars() const {
JS_ASSERT(!isRope());
return u.chars;
}
@@ -439,16 +445,22 @@ struct JSString
}
static void staticAsserts() {
JS_STATIC_ASSERT(((JSString::MAX_LENGTH << JSString::LENGTH_SHIFT) >>
JSString::LENGTH_SHIFT) == JSString::MAX_LENGTH);
}
};
+struct JSFlatString : JSString
+{
+};
+
+JS_STATIC_ASSERT(sizeof(JSFlatString) == sizeof(JSString));
+
struct JSExternalString : JSString
{
static const uintN TYPE_LIMIT = 8;
static JSStringFinalizeOp str_finalizers[TYPE_LIMIT];
static intN changeFinalizer(JSStringFinalizeOp oldop,
JSStringFinalizeOp newop) {
for (uintN i = 0; i != JS_ARRAY_LENGTH(str_finalizers); i++) {
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -2687,17 +2687,17 @@ ValueToNative(const Value &v, JSValueTyp
case JSVAL_TYPE_FUNOBJ: {
JS_ASSERT(IsFunctionObject(v));
JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &v.toObject());
#if defined JS_JIT_SPEW
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);
}
#endif
return;
}
default:
@@ -2885,17 +2885,17 @@ NativeToValue(JSContext* cx, Value& v, J
break;
case JSVAL_TYPE_FUNOBJ:
JS_ASSERT(IsFunctionObject(v));
#if defined JS_JIT_SPEW
if (LogController.lcbits & LC_TMTracer) {
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);
}
#endif
break;
case JSVAL_TYPE_STRORNULL:
debug_only_printf(LC_TMTracer, "nullablestr<%p> ", v.isNull() ? NULL : (void *)v.toString());
--- a/js/src/jsval.h
+++ b/js/src/jsval.h
@@ -261,18 +261,19 @@ typedef enum JSWhyMagic
JS_GENERATOR_CLOSING, /* exception value thrown when closing a generator */
JS_NO_CONSTANT, /* compiler sentinel value */
JS_THIS_POISON, /* used in debug builds to catch tracing errors */
JS_ARG_POISON, /* used in debug builds to catch tracing errors */
JS_SERIALIZE_NO_NODE, /* an empty subnode in the AST serializer */
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
typedef union jsval_layout
{
uint64 asBits;
struct {
union {
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1242,17 +1242,20 @@ AssertEq(JSContext *cx, uintN argc, jsva
: (argc == 3)
? JSSMSG_INVALID_ARGS
: JSSMSG_TOO_MANY_ARGS,
"assertEq");
return JS_FALSE;
}
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);
if (argc == 2) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_ASSERT_EQ_FAILED,
actual, expected);
} else {
JSAutoByteString bytes2(cx, JSVAL_TO_STRING(argv[2]));
@@ -1333,26 +1336,30 @@ GCParameter(JSContext *cx, uintN argc, j
JS_ASSERT(str);
} else {
str = JS_ValueToString(cx, vp[2]);
if (!str)
return JS_FALSE;
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)) {
JS_ReportError(cx,
"the first argument argument must be maxBytes, "
"maxMallocBytes, gcStackpoolLifespan, gcBytes, "
"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;
if (argc == 1) {
uint32 value = JS_GetGCParameter(cx->runtime, param);
return JS_NewNumberValue(cx, value, &vp[0]);
}
@@ -1489,18 +1496,21 @@ CountHeap(JSContext *cx, uintN argc, jsv
}
}
traceKind = -1;
if (argc > 1) {
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;
}
if (++i == JS_ARRAY_LENGTH(traceKindNames)) {
JSAutoByteString bytes(cx, str);
if (!!bytes)
JS_ReportError(cx, "trace kind name '%s' is unknown", bytes.ptr());
return JS_FALSE;
@@ -1661,18 +1671,23 @@ GetTrapArgs(JSContext *cx, uintN argc, j
}
static JSTrapStatus
TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
jsval closure)
{
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)) {
return JSTRAP_ERROR;
}
if (!JSVAL_IS_VOID(*rval))
return JSTRAP_RETURN;
return JSTRAP_CONTINUE;
@@ -2073,18 +2088,21 @@ static JSBool
Disassemble(JSContext *cx, uintN argc, jsval *vp)
{
jsval *argv = JS_ARGV(cx, vp);
/* Read options off early arguments */
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--;
}
if (argc == 0) {
/* Without arguments, disassemble the current script. */
if (JSStackFrame *frame = JS_GetScriptedCaller(cx, NULL)) {
@@ -2314,23 +2332,26 @@ DumpStats(JSContext *cx, uintN argc, jsv
Value value;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]);
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))
return JS_FALSE;
JSObject *obj;
if (!js_FindProperty(cx, id, &obj, &obj2, &prop))
return JS_FALSE;
if (prop) {
@@ -2612,27 +2633,30 @@ Clear(JSContext *cx, uintN argc, jsval *
JS_ClearScope(cx, obj);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
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
Clone(JSContext *cx, uintN argc, jsval *vp)
{
JSObject *funobj, *parent, *clone;
if (!argc)
@@ -2843,59 +2867,65 @@ static JSBool
split_getProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
ComplexObject *cpx;
cpx = split_get_private(cx, obj);
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;
-
- str = JSID_TO_STRING(id);
- return JS_GetUCProperty(cx, cpx->inner, JS_GetStringChars(str),
- JS_GetStringLength(str), vp);
+ JSString *str = JSID_TO_STRING(id);
+
+ 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);
return JS_TRUE;
}
return JS_TRUE;
}
static JSBool
split_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
ComplexObject *cpx;
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;
-
- str = JSID_TO_STRING(id);
- return JS_SetUCProperty(cx, cpx->inner, JS_GetStringChars(str),
- JS_GetStringLength(str), vp);
+ JSString *str = JSID_TO_STRING(id);
+
+ 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
split_delProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
ComplexObject *cpx;
jsid asId;
@@ -2970,17 +3000,17 @@ ResolveClass(JSContext *cx, JSObject *ob
return JS_TRUE;
}
static JSBool
split_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp)
{
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);
}
cpx = split_get_private(cx, obj);
if (!cpx)
return JS_TRUE;
if (!cpx->isInner && cpx->inner) {
@@ -3277,18 +3307,21 @@ NewSandbox(JSContext *cx, bool lazy, boo
static JSBool
EvalInContext(JSContext *cx, uintN argc, jsval *vp)
{
JSString *str;
JSObject *sobj = NULL;
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') {
lazy = true;
srclen = 0;
}
} else if (srclen == 5) {
if (src[0] == 's' && src[1] == 'p' && src[2] == 'l' && src[3] == 'i' && src[4] == 't') {
@@ -4541,18 +4574,21 @@ Help(JSContext *cx, uintN argc, jsval *v
fun = JS_ValueToFunction(cx, argv[i]);
str = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
} else if (type == JSTYPE_STRING) {
str = JSVAL_TO_STRING(argv[i]);
} else {
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);
}
did_something = 1;
fprintf(gOutFile, "%s\n", shell_help_messages[j]);
break;
}
--- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
@@ -195,17 +195,21 @@ Dump(JSContext *cx, uintN argc, jsval *v
JSString *str;
if (!argc)
return JS_TRUE;
str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
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;
}
static JSBool
Debug(JSContext *cx, uintN argc, jsval *vp)
{
#ifdef DEBUG
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -716,18 +716,17 @@ nsXPConnect::Traverse(void *p, nsCycleCo
}
}
else if(clazz == &js_FunctionClass)
{
JSFunction* fun = (JSFunction*) xpc_GetJSPrivate(obj);
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());
}
else
{
JS_snprintf(name, sizeof(name), "JS Object (Function)");
}
}
--- a/js/src/xpconnect/src/qsgen.py
+++ b/js/src/xpconnect/src/qsgen.py
@@ -1132,39 +1132,53 @@ traceableArgumentConversionTemplates = {
" PRUint64 ${name} = xpc_qsDoubleToUint64(${argVal});\n",
'boolean':
" PRBool ${name} = (PRBool) ${argVal};\n",
'float':
" float ${name} = (float) ${argVal};\n",
'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,
rvdeclared):
argVal = "_arg%d" % i
params = {
'name': name,
- 'argVal': argVal
+ 'argVal': argVal,
+ 'error': getFailureString(getTraceInfoDefaultReturn(member.realtype), 2)
}
typeName = getBuiltinOrNativeTypeName(type)
if typeName is not None:
template = traceableArgumentConversionTemplates.get(typeName)
if template is not None:
f.write(substitute(template, params))
return rvdeclared
--- a/js/src/xpconnect/src/xpccomponents.cpp
+++ b/js/src/xpconnect/src/xpccomponents.cpp
@@ -668,21 +668,20 @@ nsXPCComponents_InterfacesByID::NewResol
jsid id, PRUint32 flags,
JSObject * *objp, PRBool *_retval)
{
const jschar* name = nsnull;
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;
mManager->GetInfoForIID(&iid, getter_AddRefs(info));
if(!info)
return NS_OK;
nsCOMPtr<nsIJSIID> nsid =
@@ -2953,18 +2952,21 @@ nsXPCComponents_Utils::ReportError()
nsXPIDLCString fileName;
PRInt32 lineNo = 0;
if(frame)
{
frame->GetFilename(getter_Copies(fileName));
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,
0, "XPConnect JavaScript");
if(NS_SUCCEEDED(rv))
console->LogMessage(scripterr);
}
@@ -2991,22 +2993,22 @@ SandboxDump(JSContext *cx, uintN argc, j
JSString *str;
if (!argc)
return JS_TRUE;
str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
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;
#if defined(XP_MAC) || defined(XP_MACOSX)
// Be nice and convert all \r to \n.
char *c = cstr, *cEnd = cstr + strlen(cstr);
while (c < cEnd) {
@@ -3327,20 +3329,25 @@ nsXPCComponents_utils_Sandbox::CallOrCon
nsresult rv;
// Make sure to set up principals on the sandbox before initing classes
nsCOMPtr<nsIScriptObjectPrincipal> sop;
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)) {
return ThrowAndFail(rv, cx, _retval);
}
nsCOMPtr<nsIScriptSecurityManager> secman =
do_GetService(kScriptSecurityManagerContractID);
--- a/js/src/xpconnect/src/xpcconvert.cpp
+++ b/js/src/xpconnect/src/xpcconvert.cpp
@@ -169,17 +169,18 @@ XPCConvert::GetISupportsFromJSObject(JSO
/***************************************************************************/
static void
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);
}
static JSBool
AddXPCOMUCStringFinalizer()
{
@@ -608,35 +609,45 @@ XPCConvert::JSData2Native(XPCCallContext
break;
case nsXPTType::T_CHAR :
{
JSString* str = JS_ValueToString(cx, s);
if(!str)
{
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;
}
case nsXPTType::T_JSVAL :
{
if (useAllocator) {
// The C++ type is (const jsval &), which here means (jsval *).
jsval *buf = new jsval(s);
@@ -724,17 +735,17 @@ XPCConvert::JSData2Native(XPCCallContext
{
str = JS_ValueToString(cx, s);
if(!str)
return JS_FALSE;
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)
isNewString = JS_TRUE;
}
else
{
str = nsnull;
@@ -742,18 +753,23 @@ XPCConvert::JSData2Native(XPCCallContext
}
}
if(useAllocator)
{
// 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;
*((const nsAString**)d) = wrapper;
}
else if(JSVAL_IS_NULL(s))
{
XPCReadableJSStringWrapper *wrapper =
@@ -810,22 +826,22 @@ XPCConvert::JSData2Native(XPCCallContext
}
JSString* str = JS_ValueToString(cx, s);
if(!str)
{
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))
legalRange = PR_FALSE;
}
NS_ASSERTION(legalRange,"U+0080/U+0100 - U+FFFF data lost");
}
#endif // DEBUG
@@ -864,17 +880,17 @@ XPCConvert::JSData2Native(XPCCallContext
}
if(!(str = JS_ValueToString(cx, s)))
{
return JS_FALSE;
}
if(useAllocator)
{
- if(!(chars = JS_GetStringChars(str)))
+ if(!(chars = JS_GetStringCharsZ(cx, str)))
{
return JS_FALSE;
}
int len = JS_GetStringLength(str);
int byte_len = (len+1)*sizeof(jschar);
if(!(*((void**)d) = nsMemory::Alloc(byte_len)))
{
// XXX should report error
@@ -893,17 +909,17 @@ XPCConvert::JSData2Native(XPCCallContext
*((const jschar**)d) = chars;
}
return JS_TRUE;
}
case nsXPTType::T_UTF8STRING:
{
- jschar* chars;
+ const jschar* chars;
PRUint32 length;
JSString* str;
if(JSVAL_IS_NULL(s) || JSVAL_IS_VOID(s))
{
if(useAllocator)
{
nsACString *rs = new nsCString();
@@ -920,17 +936,17 @@ XPCConvert::JSData2Native(XPCCallContext
rs->SetIsVoid(PR_TRUE);
}
return JS_TRUE;
}
// 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;
}
length = JS_GetStringLength(str);
nsCString *rs;
if(useAllocator)
@@ -1024,18 +1040,17 @@ XPCConvert::JSData2Native(XPCCallContext
*((nsISupports**)d) = static_cast<nsIVariant*>(variant);
return JS_TRUE;
}
else if(iid->Equals(NS_GET_IID(nsIAtom)) &&
JSVAL_IS_STRING(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;
return JS_FALSE;
}
PRUint32 length = JS_GetStringLength(str);
nsIAtom* atom = NS_NewAtom(nsDependentSubstring(chars,
chars + length));
@@ -2407,17 +2422,17 @@ XPCConvert::JSStringWithSize2Native(XPCC
*pErr = NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING;
return JS_FALSE;
}
if(len < capacity)
len = capacity;
if(useAllocator)
{
- if(!(chars = JS_GetStringChars(str)))
+ if(!(chars = JS_GetStringCharsZ(cx, str)))
{
return JS_FALSE;
}
JSUint32 alloc_len = (len + 1) * sizeof(jschar);
if(!(*((void**)d) = nsMemory::Alloc(alloc_len)))
{
// XXX should report error
return JS_FALSE;
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -1011,20 +1011,27 @@ public:
XPCReadableJSStringWrapper(const PRUnichar *chars, size_t length) :
nsDependentString(chars, length)
{ }
XPCReadableJSStringWrapper() :
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
// XPCCallContext is ALWAYS declared as a local variable in some function;
// i.e. instance lifetime is always controled by some C++ function returning.
//
// These things are created frequently in many places. We *intentionally* do
// not inialialize all members in order to save on construction overhead.
@@ -1128,18 +1135,17 @@ public:
JSBool isSetter);
nsresult CanCallNow();
void SystemIsBeingShutDown();
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
/**
* Sets the IDispatch information for the context
* This has to be void* because of icky Microsoft macros that
* would be introduced if we included the DispatchInterface header
*/
@@ -3333,19 +3339,16 @@ class XPCStringConvert
public:
// If the string shares the readable's buffer, that buffer will
// get assigned to *sharedBuffer. Otherwise null will be
// assigned.
static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
nsStringBuffer** sharedBuffer);
- static XPCReadableJSStringWrapper *JSStringToReadable(XPCCallContext& ccx,
- JSString *str);
-
static void ShutdownDOMStringFinalizer();
private:
XPCStringConvert(); // not implemented
};
extern JSBool
XPC_JSArgumentFormatter(JSContext *cx, const char *format,
--- a/js/src/xpconnect/src/xpcquickstubs.cpp
+++ b/js/src/xpconnect/src/xpcquickstubs.cpp
@@ -696,20 +696,21 @@ xpc_qsDOMString::xpc_qsDOMString(JSConte
{
typedef implementation_type::char_traits traits;
// From the T_DOMSTRING case in XPCConvert::JSData2Native.
JSString *s = InitOrStringify<traits>(cx, v, pval, nullBehavior,
undefinedBehavior);
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;
}
xpc_qsACString::xpc_qsACString(JSContext *cx, jsval v, jsval *pval,
StringificationBehavior nullBehavior,
StringificationBehavior undefinedBehavior)
{
@@ -741,19 +742,20 @@ xpc_qsACString::xpc_qsACString(JSContext
xpc_qsAUTF8String::xpc_qsAUTF8String(JSContext *cx, jsval v, jsval *pval)
{
typedef nsCharTraits<PRUnichar> traits;
// From the T_UTF8STRING case in XPCConvert::JSData2Native.
JSString *s = InitOrStringify<traits>(cx, v, pval, eNull, eNull);
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;
}
static nsresult
getNative(nsISupports *idobj,
QITableEntry* entries,
@@ -1028,18 +1030,22 @@ xpc_qsJsvalToWcharStr(JSContext *cx, jsv
}
else
{
if(!(str = JS_ValueToString(cx, v)))
return JS_FALSE;
*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;
}
JSBool
xpc_qsStringToJsval(JSContext *cx, nsString &str, jsval *rval)
{
// From the T_DOMSTRING case in XPCConvert::NativeData2JS.
if(str.IsVoid())
--- a/js/src/xpconnect/src/xpcstring.cpp
+++ b/js/src/xpconnect/src/xpcstring.cpp
@@ -55,17 +55,19 @@
#include "xpcprivate.h"
#include "nsStringBuffer.h"
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
XPCStringConvert::ShutdownDOMStringFinalizer()
{
if (sDOMStringFinalizerIndex == -1)
return;
@@ -134,20 +136,8 @@ XPCStringConvert::ReadableToJSVal(JSCont
chars[length] = 0;
str = JS_NewUCString(cx, chars, length);
if (!str)
JS_free(cx, chars);
}
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));
-}
--- a/js/src/xpconnect/src/xpcvariant.cpp
+++ b/js/src/xpconnect/src/xpcvariant.cpp
@@ -322,21 +322,27 @@ JSBool XPCVariant::InitializeData(XPCCal
return JS_FALSE;
// Don't use nsVariant::SetFromWStringWithSize, because that will copy
// the data. Just handle this ourselves. Note that it's ok to not
// copy because we added mJSVal as a GC root.
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;
}
// leaving only JSObject...
NS_ASSERTION(JSVAL_IS_OBJECT(mJSVal), "invalid type of jsval!");
--- a/js/src/xpconnect/src/xpcwrappedjsclass.cpp
+++ b/js/src/xpconnect/src/xpcwrappedjsclass.cpp
@@ -447,20 +447,23 @@ nsXPCWrappedJSClass::BuildPropertyEnumer
jsval jsvalName;
if(!JS_IdToValue(cx, idName, &jsvalName))
goto out;
JSString* name = JS_ValueToString(cx, jsvalName);
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;
if(!propertyArray.AppendObject(property))
goto out;
}
retval = NS_NewArrayEnumerator(aEnumerate, propertyArray);
--- a/js/src/xpconnect/tests/TestXPC.cpp
+++ b/js/src/xpconnect/tests/TestXPC.cpp
@@ -547,21 +547,21 @@ TestArgFormatter(JSContext* jscontext, J
const char* a_in = "some string";
nsCOMPtr<nsITestXPCFoo> b_in = new nsTestXPCFoo();
nsCOMPtr<nsIWritableVariant> c_in = do_CreateInstance("@mozilla.org/variant;1");
static NS_NAMED_LITERAL_STRING(d_in, "foo bar");
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;
printf("ArgumentFormatter test: ");
if(!b_in || !c_in || NS_FAILED(c_in->SetAsInt32(5)))
{
@@ -583,37 +583,40 @@ TestArgFormatter(JSContext* jscontext, J
c_in.get(),
static_cast<const nsAString*>(&d_in),
e_in))
{
printf(" could not convert from native to JS -- FAILED!\n");
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)),
static_cast<nsIVariant**>(getter_AddRefs(c_out)),
static_cast<nsAString*>(&d_out),
&e_out);
TAF_CHECK(ok, " could not convert from JS to native -- FAILED!\n");
TAF_CHECK(b_out, " JS to native for %%ip returned NULL -- FAILED!\n");
specified = do_QueryInterface(b_out);
TAF_CHECK(specified, " could not QI value JS to native returned -- FAILED!\n");
ok = specified.get() == b_in.get();
TAF_CHECK(ok, " JS to native returned wrong value -- FAILED!\n");
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");
}
/***************************************************************************/
// ThreadJSContextStack test
--- a/js/src/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/src/xpconnect/wrappers/AccessCheck.cpp
@@ -104,28 +104,28 @@ nsIPrincipal *
AccessCheck::getPrincipal(JSCompartment *compartment)
{
return GetCompartmentPrincipal(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]) {
NAME('D', "DOMException",
PROP('c', RW("code"))
PROP('m', RW("message"))
PROP('n', RW("name"))
PROP('r', RW("result"))
@@ -178,18 +178,17 @@ IsFrameId(JSContext *cx, JSObject *obj,
domwin->GetFrames(getter_AddRefs(col));
if (!col) {
return false;
}
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;
}
return domwin != nsnull;
}
@@ -286,17 +285,17 @@ AccessCheck::isCrossOriginAccessPermitte
js::Class *clasp = obj->getClass();
NS_ASSERTION(Jsvalify(clasp) != &XrayUtils::HolderClass, "shouldn't have a holder here");
if (clasp->ext.innerObject)
name = "Window";
else
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;
}
if (IsWindow(name) && IsFrameId(cx, obj, id))
return true;
// We only reach this point for cross origin location objects (see
// SameOriginOrCrossOriginAccessiblePropertiesOnly::check).
@@ -413,17 +412,19 @@ AccessCheck::deny(JSContext *cx, jsid id
JS_ReportError(cx, "Permission denied to access object");
} else {
jsval idval;
if (!JS_IdToValue(cx, id, &idval))
return;
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);
}
}
typedef enum { READ = (1<<0), WRITE = (1<<1), NO_ACCESS = 0 } Access;
bool
ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, JSWrapper::Action act,
Permission &perm)
@@ -475,18 +476,21 @@ ExposedPropertiesOnly::check(JSContext *
}
if (!JSVAL_IS_STRING(desc.value)) {
JS_ReportError(cx, "property must be a string");
return false;
}
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':
if (access & READ) {
JS_ReportError(cx, "duplicate 'readable' property flag");
return false;
}
access = Access(access | READ);
--- a/modules/plugin/base/src/nsJSNPRuntime.cpp
+++ b/modules/plugin/base/src/nsJSNPRuntime.cpp
@@ -458,18 +458,23 @@ JSValToNPVariant(NPP npp, JSContext *cx,
jsint i;
if (JS_DoubleIsInt32(d, &i)) {
INT32_TO_NPVARIANT(i, *variant);
} else {
DOUBLE_TO_NPVARIANT(d, *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);
if (!p) {
return false;
}
@@ -598,26 +603,19 @@ nsJSObjWrapper::NP_Invalidate(NPObject *
// Forget our reference to the JSObject.
jsnpobj->mJSObj = nsnull;
}
}
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
bool
nsJSObjWrapper::NP_HasMethod(NPObject *npobj, NPIdentifier id)
{
NPP npp = NPPStack::Peek();
JSContext *cx = GetJSContext(npp);
@@ -791,27 +789,19 @@ nsJSObjWrapper::NP_HasProperty(NPObject
AutoCXPusher pusher(cx);
JSAutoRequest ar(cx);
AutoJSExceptionReporter reporter(cx);
JSAutoEnterCompartment ac;
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;
}
// static
bool
nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier id,
NPVariant *result)
{
@@ -872,26 +862,19 @@ nsJSObjWrapper::NP_SetProperty(NPObject
JSAutoEnterCompartment ac;
if (!ac.enter(cx, npjsobj->mJSObj))
return PR_FALSE;
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.
return ok == JS_TRUE;
}
// static
bool
@@ -918,55 +901,31 @@ nsJSObjWrapper::NP_RemoveProperty(NPObje
JSAutoRequest ar(cx);
AutoJSExceptionReporter reporter(cx);
jsval deleted = JSVAL_FALSE;
JSAutoEnterCompartment ac;
if (!ac.enter(cx, npjsobj->mJSObj))
return PR_FALSE;
- if (NPIdentifierIsString(id)) {
- JSString *str = NPIdentifierToString(id);
-
- ok = ::JS_DeleteUCProperty2(cx, npjsobj->mJSObj, ::JS_GetStringChars(str),
- ::JS_GetStringLength(str), &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_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;
- }
+ 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.
+
+ JSBool hasProp;
+ ok = ::JS_HasPropertyById(cx, npjsobj->mJSObj, NPIdentifierToJSId(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;
}
}
// return ok == JS_TRUE to quiet down compiler warning, even if
// return ok is what we really want.
return ok == JS_TRUE && deleted == JSVAL_TRUE;
}
@@ -1022,24 +981,22 @@ nsJSObjWrapper::NP_Enumerate(NPObject *n
if (!::JS_IdToValue(cx, ida->vector[i], &v)) {
::JS_DestroyIdArray(cx, ida);
PR_Free(*idarray);
return PR_FALSE;
}
NPIdentifier id;
if (JSVAL_IS_STRING(v)) {
- JSString *str = JSVAL_TO_STRING(v);
-
- if (!JS_InternUCStringN(cx, ::JS_GetStringChars(str),
- ::JS_GetStringLength(str))) {
- ::JS_DestroyIdArray(cx, ida);
- PR_Free(*idarray);
-
- return PR_FALSE;
+ JSString *str = JS_InternJSString(cx, JSVAL_TO_STRING(v));
+ if (!str) {
+ ::JS_DestroyIdArray(cx, ida);
+ PR_Free(*idarray);
+
+ return PR_FALSE;
}
id = StringToNPIdentifier(str);
} else {
NS_ASSERTION(JSVAL_IS_INT(v),
"The element in ida must be either string or int!\n");
id = IntToNPIdentifier(JSVAL_TO_INT(v));
}
@@ -1688,66 +1645,38 @@ NPObjWrapper_NewResolve(JSContext *cx, J
NPIdentifier identifier = JSIdToNPIdentifier(id);
PRBool hasProperty = npobj->_class->hasProperty(npobj, identifier);
if (!ReportExceptionIfPending(cx))
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;
return JS_TRUE;
}
PRBool hasMethod = npobj->_class->hasMethod(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return JS_FALSE;
if (hasMethod) {
- JSString *str = nsnull;
-
- 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);
+ NS_ASSERTION(JSID_IS_STRING(id) || JSID_IS_INT(id),
+ "id must be either string or int!\n");
+
+ JSFunction *fnc = ::JS_DefineFunctionById(cx, obj, id, CallNPMethod, 0,
+ JSPROP_ENUMERATE);
*objp = obj;
return fnc != nsnull;
}
// no property or method
return JS_TRUE;
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp
+++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp
@@ -1436,17 +1436,17 @@ NPUTF8* NP_CALLBACK
if (!NPIdentifierIsString(id)) {
return nsnull;
}
JSString *str = NPIdentifierToString(id);
return
- ToNewUTF8String(nsDependentString((PRUnichar *)::JS_GetStringChars(str),
+ ToNewUTF8String(nsDependentString(::JS_GetInternedStringChars(str),
::JS_GetStringLength(str)));
}
int32_t NP_CALLBACK
_intfromidentifier(NPIdentifier id)
{
if (!NS_IsMainThread()) {
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_intfromidentifier called from the wrong thread\n"));
--- a/storage/src/Makefile.in
+++ b/storage/src/Makefile.in
@@ -78,18 +78,20 @@ CPPSRCS = \
mozStorageAsyncStatement.cpp \
mozStorageAsyncStatementJSHelper.cpp \
mozStorageAsyncStatementParams.cpp \
StorageBaseStatementInternal.cpp \
SQLCollations.cpp \
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
# will need to change it here as well.
DEFINES += -DSQLITE_MAX_LIKE_PATTERN_LENGTH=50000
include $(topsrcdir)/config/rules.mk
--- a/storage/src/mozStorageAsyncStatementJSHelper.cpp
+++ b/storage/src/mozStorageAsyncStatementJSHelper.cpp
@@ -131,16 +131,16 @@ AsyncStatementJSHelper::GetProperty(nsIX
#ifdef DEBUG
{
nsISupports *supp = aWrapper->Native();
nsCOMPtr<mozIStorageAsyncStatement> isStatement(do_QueryInterface(supp));
NS_ASSERTION(isStatement, "How is this not an async statement?!");
}
#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;
}
} // namespace storage
} // namespace mozilla
--- a/storage/src/mozStorageAsyncStatementParams.cpp
+++ b/storage/src/mozStorageAsyncStatementParams.cpp
@@ -92,19 +92,19 @@ AsyncStatementParams::SetProperty(
nsCOMPtr<nsIVariant> variant(convertJSValToVariant(aCtx, *_vp));
NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED);
nsresult rv = mStatement->BindByIndex(idx, variant);
NS_ENSURE_SUCCESS(rv, rv);
}
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);
nsresult rv = mStatement->BindByName(name, variant);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
return NS_ERROR_INVALID_ARG;
@@ -136,18 +136,18 @@ AsyncStatementParams::NewResolve(
// All indexes are good because we don't know how many parameters there
// really are.
ok = ::JS_DefineElement(aCtx, aScopeObj, idx, JSVAL_VOID, nsnull,
nsnull, 0);
resolved = true;
}
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
// chain, but people really shouldn't be depending on this anyways.
ok = ::JS_DefineUCProperty(aCtx, aScopeObj, nameChars, nameLength,
JSVAL_VOID, nsnull, nsnull, 0);
resolved = true;
}
--- a/storage/src/mozStoragePrivateHelpers.cpp
+++ b/storage/src/mozStoragePrivateHelpers.cpp
@@ -44,16 +44,17 @@
#include "jsdate.h"
#include "nsPrintfCString.h"
#include "nsString.h"
#include "nsError.h"
#include "mozilla/Mutex.h"
#include "mozilla/CondVar.h"
#include "nsThreadUtils.h"
+#include "nsJSUtils.h"
#include "Variant.h"
#include "mozStoragePrivateHelpers.h"
#include "mozIStorageStatement.h"
#include "mozIStorageCompletionCallback.h"
#include "mozIStorageBindingParams.h"
namespace mozilla {
@@ -146,20 +147,19 @@ convertJSValToVariant(
if (JSVAL_IS_INT(aValue))
return new IntegerVariant(JSVAL_TO_INT(aValue));
if (JSVAL_IS_DOUBLE(aValue))
return new FloatVariant(JSVAL_TO_DOUBLE(aValue));
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);
}
if (JSVAL_IS_BOOLEAN(aValue))
return new IntegerVariant((aValue == JSVAL_TRUE) ? 1 : 0);
if (JSVAL_IS_NULL(aValue))
return new NullVariant();
--- a/storage/src/mozStorageStatementJSHelper.cpp
+++ b/storage/src/mozStorageStatementJSHelper.cpp
@@ -219,21 +219,21 @@ StatementJSHelper::GetProperty(nsIXPConn
NS_ASSERTION(isStatement, "How is this not a statement?!");
}
#endif
Statement *stmt = static_cast<Statement *>(
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;
}
NS_IMETHODIMP
StatementJSHelper::NewResolve(nsIXPConnectWrappedNative *aWrapper,
@@ -242,17 +242,17 @@ StatementJSHelper::NewResolve(nsIXPConne
jsid aId,
PRUint32 aFlags,
JSObject **_objp,
PRBool *_retval)
{
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;
return NS_OK;
}
return NS_OK;
}
--- a/storage/src/mozStorageStatementParams.cpp
+++ b/storage/src/mozStorageStatementParams.cpp
@@ -90,19 +90,20 @@ StatementParams::SetProperty(nsIXPConnec
nsCOMPtr<nsIVariant> variant(convertJSValToVariant(aCtx, *_vp));
NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED);
nsresult rv = mStatement->BindByIndex(idx, variant);
NS_ENSURE_SUCCESS(rv, rv);
}
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));
NS_ENSURE_TRUE(variant, NS_ERROR_UNEXPECTED);
nsresult rv = mStatement->BindByName(name, variant);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
@@ -206,18 +207,19 @@ StatementParams::NewResolve(nsIXPConnect
return NS_ERROR_INVALID_ARG;
ok = ::JS_DefineElement(aCtx, aScopeObj, idx, JSVAL_VOID, nsnull,
nsnull, JSPROP_ENUMERATE);
resolved = true;
}
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.
NS_ConvertUTF16toUTF8 name(reinterpret_cast<const PRUnichar *>(nameChars),
nameLength);
PRUint32 idx;
nsresult rv = mStatement->GetParameterIndex(name, &idx);
if (NS_SUCCEEDED(rv)) {
--- a/toolkit/xre/Makefile.in
+++ b/toolkit/xre/Makefile.in
@@ -189,16 +189,17 @@ endif
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(topsrcdir)/dom/ipc \
-I$(topsrcdir)/toolkit/crashreporter \
+ -I$(topsrcdir)/dom/base \
$(NULL)
ifdef BUILD_STATIC_LIBS
export::
@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMP_NAMES) Apprunner
endif
LOCAL_INCLUDES += \
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -65,16 +65,17 @@
#include "nsAppDirectoryServiceDefs.h"
#include "nsAppRunner.h"
#include "nsAutoRef.h"
#include "nsDirectoryServiceDefs.h"
#include "nsExceptionHandler.h"
#include "nsString.h"
#include "nsThreadUtils.h"
+#include "nsJSUtils.h"
#include "nsWidgetsCID.h"
#include "nsXREDirProvider.h"
#include "mozilla/Omnijar.h"
#ifdef MOZ_IPC
#if defined(XP_MACOSX)
#include "chrome/common/mach_ipc_mac.h"
#endif
@@ -672,18 +673,19 @@ TestShellParent* GetOrCreateTestShellPar
bool
XRE_SendTestShellCommand(JSContext* aCx,
JSString* aCommand,
void* aCallback)
{
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);
}
TestShellCommandParent* callback = static_cast<TestShellCommandParent*>(
tsp->SendPTestShellCommandConstructor(command));
NS_ENSURE_TRUE(callback, false);