Bug 775588 - Expose path to tmpdir, profiledir in OS.Constants and make sure that weird loaders that violate loading order do not segfault. r=khuey

--HG--
extra : rebase_source : 26df2463b84dd60ca50cc9c280f226ee692d2f4e
This commit is contained in:
David Rajchenbach-Teller 2012-08-22 16:58:08 -04:00
Родитель 96f43679ba
Коммит 336d21cc76
1 изменённых файлов: 95 добавлений и 18 удалений

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

@ -33,6 +33,9 @@
#include "nsXPCOMCIDInternal.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsAutoPtr.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "OSFileConstants.h"
#include "nsIOSFileConstantsService.h"
@ -53,10 +56,34 @@ namespace {
*/
bool gInitialized = false;
typedef struct {
/**
* The name of the directory holding all the libraries (libxpcom, libnss, etc.)
*/
nsString libDir;
nsString tmpDir;
nsString profileDir;
} Paths;
/**
* The name of the directory holding all the libraries (libxpcom, libnss, etc.)
* System directories.
*/
nsString* gLibDirectory;
Paths* gPaths = NULL;
}
/**
* Return the path to one of the special directories.
*/
nsresult GetPathToSpecialDir(const char *aKey, nsString& aOutPath)
{
nsCOMPtr<nsIFile> file;
nsresult rv = NS_GetSpecialDirectory(aKey, getter_AddRefs(file));
if (NS_FAILED(rv) || !file) {
return rv;
}
return file->GetPath(aOutPath);
}
/**
@ -72,23 +99,43 @@ nsresult InitOSFileConstants()
gInitialized = true;
// Initialize gLibDirectory
nsCOMPtr<nsIFile> xpcomLib;
nsresult rv = NS_GetSpecialDirectory("XpcomLib", getter_AddRefs(xpcomLib));
if (NS_FAILED(rv) || !xpcomLib) {
return rv;
}
nsAutoPtr<Paths> paths(new Paths);
nsCOMPtr<nsIFile> libDir;
rv = xpcomLib->GetParent(getter_AddRefs(libDir));
// Initialize paths->libDir
nsCOMPtr<nsIFile> file;
nsresult rv = NS_GetSpecialDirectory("XpcomLib", getter_AddRefs(file));
if (NS_FAILED(rv)) {
return rv;
}
gLibDirectory = new nsString();
return libDir->GetPath(*gLibDirectory);
nsCOMPtr<nsIFile> libDir;
rv = file->GetParent(getter_AddRefs(libDir));
if (NS_FAILED(rv)) {
return rv;
}
rv = libDir->GetPath(paths->libDir);
if (NS_FAILED(rv)) {
return rv;
}
rv = GetPathToSpecialDir(NS_OS_TEMP_DIR, paths->tmpDir);
if (NS_FAILED(rv)) {
return rv;
}
rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, paths->profileDir);
if (NS_FAILED(rv)) {
return rv;
}
gPaths = paths.forget();
return NS_OK;
}
/**
* Perform the cleaning up that can only be executed on the main thread.
*/
void CleanupOSFileConstants()
{
MOZ_ASSERT(NS_IsMainThread());
@ -97,7 +144,7 @@ void CleanupOSFileConstants()
}
gInitialized = false;
delete gLibDirectory;
delete gPaths;
}
@ -478,6 +525,17 @@ JSObject *GetOrCreateObjectProperty(JSContext *cx, JSObject *aObject,
return JS_DefineObject(cx, aObject, aProperty, NULL, NULL, JSPROP_ENUMERATE);
}
/**
* Set a property of an object from a nsString.
*/
bool SetStringProperty(JSContext *cx, JSObject *aObject, const char *aProperty,
const nsString aValue)
{
JSString* strValue = JS_NewUCStringCopyZ(cx, aValue.get());
jsval valValue = STRING_TO_JSVAL(strValue);
return JS_SetProperty(cx, aObject, aProperty, &valValue);
}
/**
* Define OS-specific constants.
*
@ -488,6 +546,16 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
{
MOZ_ASSERT(gInitialized);
if (gPaths == NULL) {
// If an initialization error was ignored, we may end up with
// |gInitialized == true| but |gPaths == NULL|. We cannot
// |MOZ_ASSERT| this, as this would kill precompile_cache.js,
// so we simply return an error.
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_OPEN, "OSFileConstants", "initialization has failed");
return false;
}
JSObject *objOS;
if (!(objOS = GetOrCreateObjectProperty(cx, global, "OS"))) {
return false;
@ -550,10 +618,9 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
return false;
}
// Locate libxul
{
nsAutoString xulPath(*gLibDirectory);
nsAutoString xulPath(gPaths->libDir);
xulPath.Append(PR_GetDirectorySeparator());
@ -568,13 +635,23 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
xulPath.Append(NS_LITERAL_STRING(DLL_SUFFIX));
#endif // defined(XP_MACOSX)
JSString* strPathToLibXUL = JS_NewUCStringCopyZ(cx, xulPath.get());
jsval valXul = STRING_TO_JSVAL(strPathToLibXUL);
if (!JS_SetProperty(cx, objPath, "libxul", &valXul)) {
if (!SetStringProperty(cx, objPath, "libxul", xulPath)) {
return false;
}
}
if (!SetStringProperty(cx, objPath, "libDir", gPaths->libDir)) {
return false;
}
if (!SetStringProperty(cx, objPath, "tmpDir", gPaths->tmpDir)) {
return false;
}
if (!SetStringProperty(cx, objPath, "profileDir", gPaths->profileDir)) {
return false;
}
return true;
}