Bug 647337 - rm script filename prefix and flag stuff (r=mrbkap)

This commit is contained in:
Luke Wagner 2011-04-07 14:25:32 -07:00
Родитель a307ff15f9
Коммит 7cc466a826
16 изменённых файлов: 27 добавлений и 334 удалений

Просмотреть файл

@ -895,13 +895,6 @@ nsChromeRegistryChrome::ManifestContent(ManifestProcessingContext& cx, int linen
entry->flags |= PLATFORM_PACKAGE;
if (contentaccessible)
entry->flags |= CONTENT_ACCESSIBLE;
if (cx.GetXPConnect()) {
nsCAutoString urlp("chrome://");
urlp.Append(package);
urlp.Append('/');
cx.GetXPConnect()->FlagSystemFilenamePrefix(urlp.get(), true);
}
}
void

Просмотреть файл

@ -670,7 +670,6 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
if (global) {
JSPrincipals* jsprin = nsnull;
mPrincipal->GetJSPrincipals(mCx, &jsprin);
nsContentUtils::XPConnect()->FlagSystemFilenamePrefix(url.get(), PR_TRUE);
uint32 oldopts = JS_GetOptions(mCx);
JS_SetOptions(mCx, oldopts | JSOPTION_NO_SCRIPT_RVAL);

Просмотреть файл

@ -315,11 +315,9 @@ nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, PRBool *aIsInterval,
mExpr = expr;
nsIPrincipal *prin = aWindow->GetPrincipal();
// Get the calling location.
const char *filename;
if (nsJSUtils::GetCallingLocation(cx, &filename, &mLineNo, prin)) {
if (nsJSUtils::GetCallingLocation(cx, &filename, &mLineNo)) {
mFileName.Assign(filename);
}
} else if (funobj) {

Просмотреть файл

@ -62,7 +62,7 @@
JSBool
nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
PRUint32* aLineno, nsIPrincipal* aPrincipal)
PRUint32* aLineno)
{
// Get the current filename and line number
JSStackFrame* frame = nsnull;
@ -76,29 +76,6 @@ nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
} while (frame && !script);
if (script) {
// If aPrincipals is non-null then our caller is asking us to ensure
// that the filename we return does not have elevated privileges.
if (aPrincipal) {
uint32 flags = JS_GetScriptFilenameFlags(script);
// Use the principal for the filename if it shouldn't be receiving
// implicit XPCNativeWrappers.
PRBool system;
if (flags & JSFILENAME_PROTECTED) {
nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
if (NS_FAILED(ssm->IsSystemPrincipal(aPrincipal, &system)) || !system) {
JSPrincipals* jsprins;
aPrincipal->GetJSPrincipals(aContext, &jsprins);
*aFilename = jsprins->codebase;
*aLineno = 0;
JSPRINCIPALS_DROP(aContext, jsprins);
return JS_TRUE;
}
}
}
const char* filename = ::JS_GetScriptFilename(aContext, script);
if (filename) {

Просмотреть файл

@ -58,7 +58,7 @@ class nsJSUtils
{
public:
static JSBool GetCallingLocation(JSContext* aContext, const char* *aFilename,
PRUint32* aLineno, nsIPrincipal* aPrincipal);
PRUint32* aLineno);
static nsIScriptGlobalObject *GetStaticScriptGlobal(JSContext* aContext,
JSObject* aObj);

Просмотреть файл

@ -170,7 +170,7 @@ nsDOMWorkerTimeout::ExpressionCallback::ExpressionCallback(PRUint32 aArgc,
// Get the calling location.
const char* fileName;
PRUint32 lineNumber;
if (nsJSUtils::GetCallingLocation(aCx, &fileName, &lineNumber, nsnull)) {
if (nsJSUtils::GetCallingLocation(aCx, &fileName, &lineNumber)) {
mFileName.Assign(fileName);
mLineNumber = lineNumber;
}

Просмотреть файл

@ -1218,7 +1218,6 @@ struct JSRuntime {
/* Script filename table. */
struct JSHashTable *scriptFilenameTable;
JSCList scriptFilenamePrefixes;
#ifdef JS_THREADSAFE
PRLock *scriptFilenameTableLock;
#endif

Просмотреть файл

@ -1989,36 +1989,6 @@ JS_GetScriptTotalSize(JSContext *cx, JSScript *script)
return nbytes;
}
JS_PUBLIC_API(uint32)
JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp)
{
if (!fp)
fp = js_GetTopStackFrame(cx);
while (fp) {
if (fp->isScriptFrame())
return JS_GetScriptFilenameFlags(fp->script());
fp = fp->prev();
}
return 0;
}
JS_PUBLIC_API(uint32)
JS_GetScriptFilenameFlags(JSScript *script)
{
JS_ASSERT(script);
if (!script->filename)
return JSFILENAME_NULL;
return js_GetScriptFilenameFlags(script->filename);
}
JS_PUBLIC_API(JSBool)
JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags)
{
if (!js_SaveScriptFilenameRT(rt, prefix, flags))
return JS_FALSE;
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_IsSystemObject(JSContext *cx, JSObject *obj)
{

Просмотреть файл

@ -481,40 +481,6 @@ JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun);
extern JS_PUBLIC_API(size_t)
JS_GetScriptTotalSize(JSContext *cx, JSScript *script);
/*
* Get the top-most running script on cx starting from fp, or from the top of
* cx's frame stack if fp is null, and return its script filename flags. If
* the script has a null filename member, return JSFILENAME_NULL.
*/
extern JS_PUBLIC_API(uint32)
JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp);
/*
* Get the script filename flags for the script. If the script doesn't have a
* filename, return JSFILENAME_NULL.
*/
extern JS_PUBLIC_API(uint32)
JS_GetScriptFilenameFlags(JSScript *script);
/*
* Associate flags with a script filename prefix in rt, so that any subsequent
* script compilation will inherit those flags if the script's filename is the
* same as prefix, or if prefix is a substring of the script's filename.
*
* The API defines only one flag bit, JSFILENAME_SYSTEM, leaving the remaining
* 31 bits up to the API client to define. The union of all 32 bits must not
* be a legal combination, however, in order to preserve JSFILENAME_NULL as a
* unique value. API clients may depend on JSFILENAME_SYSTEM being a set bit
* in JSFILENAME_NULL -- a script with a null filename member is presumed to
* be a "system" script.
*/
extern JS_PUBLIC_API(JSBool)
JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags);
#define JSFILENAME_NULL 0xffffffff /* null script filename */
#define JSFILENAME_SYSTEM 0x00000001 /* "system" script, see below */
#define JSFILENAME_PROTECTED 0x00000002 /* scripts need protection */
/*
* Return true if obj is a "system" object, that is, one created by
* JS_NewSystemObject with the system flag set and not JS_NewObject.

Просмотреть файл

@ -50,8 +50,6 @@
# include "prthread.h"
#endif
JS_BEGIN_EXTERN_C
#ifdef JS_THREADSAFE
#if (defined(_WIN32) && defined(_M_IX86)) || \
@ -217,13 +215,10 @@ js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
#define JS_ATOMIC_SET_MASK(w, mask) (*(w) |= (mask))
#define JS_ATOMIC_CLEAR_MASK(w, mask) (*(w) &= ~(mask))
#endif /* JS_THREADSAFE */
#endif
JS_END_EXTERN_C
#if defined JS_THREADSAFE && defined __cplusplus
#ifdef JS_THREADSAFE
namespace js {
class AutoLock {
private:
JSLock *lock;
@ -232,8 +227,10 @@ class AutoLock {
AutoLock(JSLock *lock) : lock(lock) { JS_ACQUIRE_LOCK(lock); }
~AutoLock() { JS_RELEASE_LOCK(lock); }
};
}
} /* namespace js */
# define JS_AUTO_LOCK_GUARD(name, l) AutoLock name((l));
#else
# define JS_AUTO_LOCK_GUARD(name, l)
#endif
#endif /* jslock_h___ */

Просмотреть файл

@ -983,20 +983,6 @@ const char *
js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
JSPrincipals *principals, uintN *linenop)
{
uint32 flags;
#ifdef DEBUG
JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx);
#endif
JS_ASSERT(principals || !(callbacks && callbacks->findObjectPrincipals));
flags = JS_GetScriptFilenameFlags(caller->script());
if ((flags & JSFILENAME_PROTECTED) &&
principals &&
strcmp(principals->codebase, "[System Principal]")) {
*linenop = 0;
return principals->codebase;
}
jsbytecode *pc = caller->pc(cx);
if (pc && js_GetOpcode(cx, caller->script(), pc) == JSOP_EVAL) {
JS_ASSERT(js_GetOpcode(cx, caller->script(), pc + JSOP_EVAL_LENGTH) == JSOP_LINENO);

Просмотреть файл

@ -307,6 +307,9 @@ enum ScriptBits {
UsesArguments
};
static const char *
SaveScriptFilename(JSContext *cx, const char *filename);
JSBool
js_XDRScript(JSXDRState *xdr, JSScript **scriptp)
{
@ -603,7 +606,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp)
if (xdr->mode == JSXDR_DECODE && state->filename) {
if (!state->filenameSaved) {
const char *filename = state->filename;
filename = js_SaveScriptFilename(xdr->cx, filename);
filename = SaveScriptFilename(xdr->cx, filename);
xdr->cx->free_((void *) state->filename);
state->filename = filename;
state->filenameSaved = true;
@ -795,7 +798,6 @@ typedef struct ScriptFilenameEntry {
JSHashEntry *next; /* hash chain linkage */
JSHashNumber keyHash; /* key hash function result */
const void *key; /* ptr to filename, below */
uint32 flags; /* user-defined filename prefix flags */
JSPackedBool mark; /* GC mark flag */
char filename[3]; /* two or more bytes, NUL-terminated */
} ScriptFilenameEntry;
@ -866,108 +868,40 @@ js_InitRuntimeScriptState(JSRuntime *rt)
FinishRuntimeScriptState(rt); /* free lock if threadsafe */
return JS_FALSE;
}
JS_INIT_CLIST(&rt->scriptFilenamePrefixes);
return JS_TRUE;
}
typedef struct ScriptFilenamePrefix {
JSCList links; /* circular list linkage for easy deletion */
const char *name; /* pointer to pinned ScriptFilenameEntry string */
size_t length; /* prefix string length, precomputed */
uint32 flags; /* user-defined flags to inherit from this prefix */
} ScriptFilenamePrefix;
void
js_FreeRuntimeScriptState(JSRuntime *rt)
{
if (!rt->scriptFilenameTable)
return;
while (!JS_CLIST_IS_EMPTY(&rt->scriptFilenamePrefixes)) {
ScriptFilenamePrefix *sfp = (ScriptFilenamePrefix *)
rt->scriptFilenamePrefixes.next;
JS_REMOVE_LINK(&sfp->links);
UnwantedForeground::free_(sfp);
}
FinishRuntimeScriptState(rt);
}
#ifdef DEBUG_brendan
#define DEBUG_SFTBL
#endif
#ifdef DEBUG_SFTBL
size_t sftbl_savings = 0;
#endif
static ScriptFilenameEntry *
SaveScriptFilename(JSRuntime *rt, const char *filename, uint32 flags)
static const char *
SaveScriptFilename(JSContext *cx, const char *filename)
{
JSHashTable *table;
JSHashNumber hash;
JSHashEntry **hep;
ScriptFilenameEntry *sfe;
size_t length;
JSCList *head, *link;
ScriptFilenamePrefix *sfp;
JSRuntime *rt = cx->runtime;
JS_AUTO_LOCK_GUARD(g, rt->scriptFilenameTableLock);
table = rt->scriptFilenameTable;
hash = JS_HashString(filename);
hep = JS_HashTableRawLookup(table, hash, filename);
sfe = (ScriptFilenameEntry *) *hep;
#ifdef DEBUG_SFTBL
if (sfe)
sftbl_savings += strlen(sfe->filename);
#endif
JSHashTable *table = rt->scriptFilenameTable;
JSHashNumber hash = JS_HashString(filename);
JSHashEntry **hep = JS_HashTableRawLookup(table, hash, filename);
ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) *hep;
if (!sfe) {
sfe = (ScriptFilenameEntry *)
JS_HashTableRawAdd(table, hep, hash, filename, NULL);
if (!sfe)
if (!sfe) {
JS_ReportOutOfMemory(cx);
return NULL;
}
sfe->key = strcpy(sfe->filename, filename);
sfe->flags = 0;
sfe->mark = JS_FALSE;
}
/* If saving a prefix, add it to the set in rt->scriptFilenamePrefixes. */
if (flags != 0) {
/* Search in case filename was saved already; we must be idempotent. */
sfp = NULL;
length = strlen(filename);
for (head = link = &rt->scriptFilenamePrefixes;
link->next != head;
link = link->next) {
/* Lag link behind sfp to insert in non-increasing length order. */
sfp = (ScriptFilenamePrefix *) link->next;
if (!strcmp(sfp->name, filename))
break;
if (sfp->length <= length) {
sfp = NULL;
break;
}
sfp = NULL;
}
if (!sfp) {
/* No such prefix: add one now. */
sfp = (ScriptFilenamePrefix *) rt->malloc_(sizeof(ScriptFilenamePrefix));
if (!sfp)
return NULL;
JS_INSERT_AFTER(&sfp->links, link);
sfp->name = sfe->filename;
sfp->length = length;
sfp->flags = 0;
}
/*
* Accumulate flags in both sfe and sfp: sfe for later access from the
* JS_GetScriptedCallerFilenameFlags debug-API, and sfp so that longer
* filename entries can inherit by prefix.
*/
sfe->flags |= flags;
sfp->flags |= flags;
}
#ifdef DEBUG
if (rt->functionMeterFilename) {
size_t len = strlen(sfe->filename);
@ -978,59 +912,6 @@ SaveScriptFilename(JSRuntime *rt, const char *filename, uint32 flags)
}
#endif
return sfe;
}
const char *
js_SaveScriptFilename(JSContext *cx, const char *filename)
{
JSRuntime *rt;
ScriptFilenameEntry *sfe;
JSCList *head, *link;
ScriptFilenamePrefix *sfp;
rt = cx->runtime;
JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);
sfe = SaveScriptFilename(rt, filename, 0);
if (!sfe) {
JS_RELEASE_LOCK(rt->scriptFilenameTableLock);
JS_ReportOutOfMemory(cx);
return NULL;
}
/*
* Try to inherit flags by prefix. We assume there won't be more than a
* few (dozen! ;-) prefixes, so linear search is tolerable.
* XXXbe every time I've assumed that in the JS engine, I've been wrong!
*/
for (head = &rt->scriptFilenamePrefixes, link = head->next;
link != head;
link = link->next) {
sfp = (ScriptFilenamePrefix *) link;
if (!strncmp(sfp->name, filename, sfp->length)) {
sfe->flags |= sfp->flags;
break;
}
}
JS_RELEASE_LOCK(rt->scriptFilenameTableLock);
return sfe->filename;
}
const char *
js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags)
{
ScriptFilenameEntry *sfe;
/* This may be called very early, via the jsdbgapi.h entry point. */
if (!rt->scriptFilenameTable && !js_InitRuntimeScriptState(rt))
return NULL;
JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);
sfe = SaveScriptFilename(rt, filename, flags);
JS_RELEASE_LOCK(rt->scriptFilenameTableLock);
if (!sfe)
return NULL;
return sfe->filename;
}
@ -1048,16 +929,6 @@ js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags)
*/
#define ASSERT_VALID_SFE(sfe) JS_ASSERT((sfe)->key == (sfe)->filename)
uint32
js_GetScriptFilenameFlags(const char *filename)
{
ScriptFilenameEntry *sfe;
sfe = FILENAME_TO_SFE(filename);
ASSERT_VALID_SFE(sfe);
return sfe->flags;
}
void
js_MarkScriptFilename(const char *filename)
{
@ -1080,9 +951,6 @@ js_script_filename_marker(JSHashEntry *he, intN i, void *arg)
void
js_MarkScriptFilenames(JSRuntime *rt)
{
JSCList *head, *link;
ScriptFilenamePrefix *sfp;
if (!rt->scriptFilenameTable)
return;
@ -1091,12 +959,6 @@ js_MarkScriptFilenames(JSRuntime *rt)
js_script_filename_marker,
rt);
}
for (head = &rt->scriptFilenamePrefixes, link = head->next;
link != head;
link = link->next) {
sfp = (ScriptFilenamePrefix *) link;
js_MarkScriptFilename(sfp->name);
}
}
static intN
@ -1123,11 +985,6 @@ js_SweepScriptFilenames(JSRuntime *rt)
JS_HashTableEnumerateEntries(rt->scriptFilenameTable,
js_script_filename_sweeper,
rt);
#ifdef DEBUG_notme
#ifdef DEBUG_SFTBL
printf("script filename table savings so far: %u\n", sftbl_savings);
#endif
#endif
}
/*
@ -1419,7 +1276,7 @@ JSScript::NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
filename = cg->parser->tokenStream.getFilename();
if (filename) {
script->filename = js_SaveScriptFilename(cx, filename);
script->filename = SaveScriptFilename(cx, filename);
if (!script->filename)
goto bad;
}

Просмотреть файл

@ -676,15 +676,6 @@ js_InitRuntimeScriptState(JSRuntime *rt);
extern void
js_FreeRuntimeScriptState(JSRuntime *rt);
extern const char *
js_SaveScriptFilename(JSContext *cx, const char *filename);
extern const char *
js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags);
extern uint32
js_GetScriptFilenameFlags(const char *filename);
extern void
js_MarkScriptFilename(const char *filename);

Просмотреть файл

@ -400,7 +400,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
%}
[uuid(fb780ace-dced-432b-bb82-8df7d4f919c8)]
[uuid(f99ffb06-4e7b-4bab-83d4-7d573235a08a)]
interface nsIXPConnect : nsISupports
{
%{ C++
@ -674,21 +674,6 @@ interface nsIXPConnect : nsISupports
jsval variantToJS(in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value);
nsIVariant JSToVariant(in JSContextPtr ctx, in jsval value);
/**
* Preconfigure XPCNativeWrapper automation so that when a scripted
* caller whose filename starts with filenamePrefix accesses a wrapped
* native that is not flagged as "system", the wrapped native will be
* automatically wrapped with an XPCNativeWrapper.
*
* @param aFilenamePrefix the UTF-8 filename prefix to match, which
* should end with a slash (/) character
* @param aWantNativeWrappers whether XPConnect should produce native
* wrappers for scripts whose paths begin
* with this prefix
*/
void flagSystemFilenamePrefix(in string aFilenamePrefix,
in PRBool aWantNativeWrappers);
/**
* Restore an old prototype for wrapped natives of type
* aClassInfo. This should be used only when restoring an old

Просмотреть файл

@ -1189,14 +1189,6 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
return NS_ERROR_FAILURE;
}
// Flag this script as a system script
// FIXME: BUG 346139: We actually want to flag this exact filename, not
// anything that starts with this filename... Maybe we need a way to do
// that? On the other hand, the fact that this is in our components dir
// means that if someone snuck a malicious file into this dir we're screwed
// anyway... So maybe flagging as a prefix is fine.
xpc->FlagSystemFilenamePrefix(nativePath.get(), PR_TRUE);
#ifdef DEBUG_shaver_off
fprintf(stderr, "mJCL: compiled JS component %s\n",
nativePath.get());

Просмотреть файл

@ -2360,23 +2360,6 @@ nsXPConnect::JSToVariant(JSContext* ctx, const jsval &value, nsIVariant** _retva
return NS_OK;
}
/* void flagSystemFilenamePrefix (in string filenamePrefix,
* in PRBool aWantNativeWrappers); */
NS_IMETHODIMP
nsXPConnect::FlagSystemFilenamePrefix(const char *aFilenamePrefix,
PRBool aWantNativeWrappers)
{
NS_PRECONDITION(aFilenamePrefix, "bad param");
JSRuntime* rt = GetRuntime()->GetJSRuntime();;
uint32 flags = JSFILENAME_SYSTEM;
if(aWantNativeWrappers)
flags |= JSFILENAME_PROTECTED;
if(!JS_FlagScriptFilenamePrefix(rt, aFilenamePrefix, flags))
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsXPConnect::OnProcessNextEvent(nsIThreadInternal *aThread, PRBool aMayWait,
PRUint32 aRecursionDepth)