зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1492090
- Part 5: Use UTF-8 for script file names. r=nbp
Differential Revision: https://phabricator.services.mozilla.com/D151449
This commit is contained in:
Родитель
5c1fd21f5e
Коммит
e56b840bda
|
@ -116,7 +116,7 @@ static bool Load(JSContext* cx, unsigned argc, JS::Value* vp) {
|
|||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
JS::UniqueChars filename = JS_EncodeStringToLatin1(cx, str);
|
||||
JS::UniqueChars filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -125,9 +125,8 @@ extern JS_PUBLIC_API bool Evaluate(JSContext* cx,
|
|||
|
||||
/**
|
||||
* Evaluate the UTF-8 contents of the file at the given path, and return the
|
||||
* completion value in |rval|. (The path itself is in the system encoding, not
|
||||
* [necessarily] UTF-8.) If the contents contain any malformed UTF-8, an error
|
||||
* is reported.
|
||||
* completion value in |rval|. (The path itself is UTF-8 encoded, too.) If
|
||||
* the contents contain any malformed UTF-8, an error is reported.
|
||||
*/
|
||||
extern JS_PUBLIC_API bool EvaluateUtf8Path(
|
||||
JSContext* cx, const ReadOnlyCompileOptions& options, const char* filename,
|
||||
|
|
|
@ -123,8 +123,12 @@ class JS_PUBLIC_API TransitiveCompileOptions {
|
|||
protected:
|
||||
// non-POD options:
|
||||
|
||||
// UTF-8 encoded file name.
|
||||
const char* filename_ = nullptr;
|
||||
|
||||
// UTF-8 encoded introducer file name.
|
||||
const char* introducerFilename_ = nullptr;
|
||||
|
||||
const char16_t* sourceMapURL_ = nullptr;
|
||||
|
||||
// POD options:
|
||||
|
|
|
@ -111,7 +111,7 @@ class JSErrorBase {
|
|||
JS::ConstUTF8CharsZ message_;
|
||||
|
||||
public:
|
||||
// Source file name, URL, etc., or null.
|
||||
// The UTF-8 encoded source file name, URL, etc., or null.
|
||||
const char* filename;
|
||||
|
||||
// Unique identifier for the script source.
|
||||
|
|
|
@ -267,7 +267,7 @@ class NodeBuilder {
|
|||
FrontendContext* fc;
|
||||
frontend::Parser<frontend::FullParseHandler, char16_t>* parser;
|
||||
bool saveLoc; /* save source location information? */
|
||||
char const* src; /* source filename or null */
|
||||
char const* src; /* UTF-8 encoded source filename or null */
|
||||
RootedValue srcval; /* source filename JS value or null */
|
||||
|
||||
public:
|
||||
|
@ -276,7 +276,7 @@ class NodeBuilder {
|
|||
|
||||
[[nodiscard]] bool init() {
|
||||
if (src) {
|
||||
if (!atomValue(src, &srcval)) {
|
||||
if (!atomValueUtf8(src, &srcval)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -292,6 +292,8 @@ class NodeBuilder {
|
|||
|
||||
private:
|
||||
[[nodiscard]] bool atomValue(const char* s, MutableHandleValue dst) {
|
||||
MOZ_ASSERT(JS::StringIsASCII(s));
|
||||
|
||||
/*
|
||||
* Bug 575416: instead of Atomize, lookup constant atoms in tbl file
|
||||
*/
|
||||
|
@ -304,6 +306,16 @@ class NodeBuilder {
|
|||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool atomValueUtf8(const char* s, MutableHandleValue dst) {
|
||||
Rooted<JSAtom*> atom(cx, AtomizeUTF8Chars(cx, s, strlen(s)));
|
||||
if (!atom) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dst.setString(atom);
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool newObject(MutableHandleObject dst) {
|
||||
Rooted<PlainObject*> nobj(cx, NewPlainObject(cx));
|
||||
if (!nobj) {
|
||||
|
@ -3642,7 +3654,7 @@ static bool reflect_parse(JSContext* cx, uint32_t argc, Value* vp) {
|
|||
return false;
|
||||
}
|
||||
|
||||
filename = EncodeLatin1(cx, str);
|
||||
filename = StringToNewUTF8CharsZ(cx, *str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -7520,7 +7520,8 @@ static bool GetLcovInfo(JSContext* cx, unsigned argc, Value* vp) {
|
|||
return false;
|
||||
}
|
||||
|
||||
JSString* str = JS_NewStringCopyN(cx, content.get(), length);
|
||||
JSString* str =
|
||||
JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(content.get(), length));
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <stdint.h> // uint32_t
|
||||
|
||||
#include "jsapi.h" // JS_NewPlainObject, JS_WrapValue
|
||||
#include "js/CharacterEncoding.h" // JS_EncodeStringToLatin1
|
||||
#include "js/CharacterEncoding.h" // JS_EncodeStringToUTF8
|
||||
#include "js/CompileOptions.h" // JS::CompileOptions
|
||||
#include "js/Conversions.h" // JS::ToBoolean, JS::ToString, JS::ToUint32, JS::ToInt32
|
||||
#include "js/PropertyAndElement.h" // JS_GetProperty, JS_DefineProperty
|
||||
|
@ -50,7 +50,7 @@ bool js::ParseCompileOptions(JSContext* cx, JS::CompileOptions& options,
|
|||
return false;
|
||||
}
|
||||
if (fileNameBytes) {
|
||||
*fileNameBytes = JS_EncodeStringToLatin1(cx, s);
|
||||
*fileNameBytes = JS_EncodeStringToUTF8(cx, s);
|
||||
if (!*fileNameBytes) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -370,7 +370,7 @@ bool js::ParseEvalOptions(JSContext* cx, HandleValue value,
|
|||
if (!url_str) {
|
||||
return false;
|
||||
}
|
||||
UniqueChars url_bytes = JS_EncodeStringToLatin1(cx, url_str);
|
||||
UniqueChars url_bytes = JS_EncodeStringToUTF8(cx, url_str);
|
||||
if (!url_bytes) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2439,7 +2439,8 @@ static bool RememberSourceURL(JSContext* cx, HandleScript script) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RootedString filenameString(cx, JS_AtomizeString(cx, filename));
|
||||
RootedString filenameString(cx,
|
||||
AtomizeUTF8Chars(cx, filename, strlen(filename)));
|
||||
if (!filenameString) {
|
||||
return false;
|
||||
}
|
||||
|
@ -5422,7 +5423,8 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery : public Debugger::QueryBase {
|
|||
// Compute urlCString and displayURLChars, if a url or displayURL was
|
||||
// given respectively.
|
||||
if (url.isString()) {
|
||||
urlCString = JS_EncodeStringToLatin1(cx, url.toString());
|
||||
Rooted<JSString*> str(cx, url.toString());
|
||||
urlCString = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!urlCString) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "vm/JSContext.h" // for ProtectedDataContextArg, JSContext
|
||||
#include "vm/JSScript.h" // for JSScript
|
||||
#include "vm/Realm.h" // for AutoRealm, Realm
|
||||
#include "vm/Warnings.h" // for WarnNumberLatin1
|
||||
#include "vm/Warnings.h" // for WarnNumberUTF8
|
||||
|
||||
#include "gc/StableCellHasher-inl.h"
|
||||
#include "vm/Realm-inl.h" // for AutoRealm::AutoRealm
|
||||
|
@ -76,14 +76,13 @@ bool EnterDebuggeeNoExecute::reportIfFoundInStack(JSContext* cx,
|
|||
const char* filename = script->filename() ? script->filename() : "(none)";
|
||||
char linenoStr[15];
|
||||
SprintfLiteral(linenoStr, "%u", script->lineno());
|
||||
// FIXME: filename should be UTF-8 (bug 987069).
|
||||
if (warning) {
|
||||
return WarnNumberLatin1(cx, JSMSG_DEBUGGEE_WOULD_RUN, filename,
|
||||
linenoStr);
|
||||
return WarnNumberUTF8(cx, JSMSG_DEBUGGEE_WOULD_RUN, filename,
|
||||
linenoStr);
|
||||
}
|
||||
|
||||
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_DEBUGGEE_WOULD_RUN, filename, linenoStr);
|
||||
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_DEBUGGEE_WOULD_RUN, filename, linenoStr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -347,11 +347,12 @@ bool DebuggerScript::CallData::getUrl() {
|
|||
|
||||
if (script->filename()) {
|
||||
JSString* str;
|
||||
if (script->scriptSource()->introducerFilename()) {
|
||||
str = NewStringCopyZ<CanGC>(cx,
|
||||
script->scriptSource()->introducerFilename());
|
||||
if (const char* introducer = script->scriptSource()->introducerFilename()) {
|
||||
str =
|
||||
NewStringCopyUTF8N(cx, JS::UTF8Chars(introducer, strlen(introducer)));
|
||||
} else {
|
||||
str = NewStringCopyZ<CanGC>(cx, script->filename());
|
||||
const char* filename = script->filename();
|
||||
str = NewStringCopyUTF8N(cx, JS::UTF8Chars(filename, strlen(filename)));
|
||||
}
|
||||
if (!str) {
|
||||
return false;
|
||||
|
|
|
@ -301,8 +301,9 @@ class DebuggerSourceGetURLMatcher {
|
|||
ReturnType match(Handle<ScriptSourceObject*> sourceObject) {
|
||||
ScriptSource* ss = sourceObject->source();
|
||||
MOZ_ASSERT(ss);
|
||||
if (ss->filename()) {
|
||||
JSString* str = NewStringCopyZ<CanGC>(cx_, ss->filename());
|
||||
if (const char* filename = ss->filename()) {
|
||||
JS::UTF8Chars utf8chars(filename, strlen(filename));
|
||||
JSString* str = NewStringCopyUTF8N(cx_, utf8chars);
|
||||
return Some(str);
|
||||
}
|
||||
return Nothing();
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// |jit-test| error:unsafe filename: (invalid UTF-8 filename)
|
||||
// |jit-test| error:unsafe filename:
|
||||
setTestFilenameValidationCallback();
|
||||
evaluate("throw 2", {fileName: "\uDEFF"});
|
||||
|
|
|
@ -2,10 +2,9 @@ if (typeof disassemble !== "function") {
|
|||
quit();
|
||||
}
|
||||
|
||||
// Invalid UTF-8 should be replaced with U+FFFD.
|
||||
const out = evaluate(`
|
||||
disassemble();
|
||||
`, {
|
||||
fileName: String.fromCharCode(3823486100),
|
||||
});
|
||||
assertEq(out.includes(`"file": "\uFFFD",`), true);
|
||||
assertEq(out.includes(`"file": "\uC494",`), true);
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
// |jit-test| skip-if: isLcovEnabled()
|
||||
// Skip this test on Lcov because the invalid filename breaks the test harness.
|
||||
|
||||
// Some filename handling code still uses latin1, and some characters are
|
||||
// replaced with REPLACEMENT CHARACTER (U+FFFD).
|
||||
//
|
||||
// FIXME: bug 1492090
|
||||
|
||||
const backtrace = evaluate(`
|
||||
this.getBacktrace(this);
|
||||
`, { fileName: "\u86D9" });
|
||||
|
||||
assertEq(backtrace.includes(`["\uFFFD":2:5]`), true);
|
||||
assertEq(backtrace.includes(`["\u86D9":2:5]`), true);
|
||||
|
|
|
@ -323,9 +323,15 @@ void js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
|
|||
return;
|
||||
}
|
||||
|
||||
RootedString fileName(cx, JS_NewStringCopyZ(cx, reportp->filename));
|
||||
if (!fileName) {
|
||||
return;
|
||||
Rooted<JSString*> fileName(cx);
|
||||
if (const char* filename = reportp->filename) {
|
||||
fileName =
|
||||
JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(filename, strlen(filename)));
|
||||
if (!fileName) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
fileName = cx->emptyString();
|
||||
}
|
||||
|
||||
uint32_t sourceId = reportp->sourceId;
|
||||
|
|
|
@ -459,7 +459,7 @@ JSObject* ModuleLoader::loadAndParse(JSContext* cx, HandleString pathArg) {
|
|||
return module;
|
||||
}
|
||||
|
||||
UniqueChars filename = JS_EncodeStringToLatin1(cx, path);
|
||||
UniqueChars filename = JS_EncodeStringToUTF8(cx, path);
|
||||
if (!filename) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "shell/OSObject.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/TextUtils.h"
|
||||
|
||||
|
@ -17,6 +18,7 @@
|
|||
# include <direct.h>
|
||||
# include <process.h>
|
||||
# include <string.h>
|
||||
# include <wchar.h>
|
||||
# include <windows.h>
|
||||
#elif __wasi__
|
||||
# include <dirent.h>
|
||||
|
@ -95,18 +97,28 @@ bool IsAbsolutePath(JSLinearString* filename) {
|
|||
|
||||
static UniqueChars DirectoryName(JSContext* cx, const char* path) {
|
||||
#ifdef XP_WIN
|
||||
char dirName[PATH_MAX + 1];
|
||||
char* drive = nullptr;
|
||||
char* fileName = nullptr;
|
||||
char* fileExt = nullptr;
|
||||
UniqueWideChars widePath = JS::EncodeUtf8ToWide(cx, path);
|
||||
if (!widePath) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wchar_t dirName[PATH_MAX + 1];
|
||||
wchar_t* drive = nullptr;
|
||||
wchar_t* fileName = nullptr;
|
||||
wchar_t* fileExt = nullptr;
|
||||
|
||||
// The docs say it can return EINVAL, but the compiler says it's void
|
||||
_splitpath(path, drive, dirName, fileName, fileExt);
|
||||
_wsplitpath(widePath.get(), drive, dirName, fileName, fileExt);
|
||||
|
||||
return DuplicateString(cx, dirName);
|
||||
return JS::EncodeWideToUtf8(cx, dirName);
|
||||
#else
|
||||
UniqueChars narrowPath = JS::EncodeUtf8ToNarrow(cx, path);
|
||||
if (!narrowPath) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char dirName[PATH_MAX + 1];
|
||||
strncpy(dirName, path, PATH_MAX);
|
||||
strncpy(dirName, narrowPath.get(), PATH_MAX);
|
||||
if (dirName[PATH_MAX - 1] != '\0') {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -140,7 +152,7 @@ static UniqueChars DirectoryName(JSContext* cx, const char* path) {
|
|||
memmove(dirName, dirname(dirName), strlen(dirName) + 1);
|
||||
# endif
|
||||
|
||||
return DuplicateString(cx, dirName);
|
||||
return JS::EncodeNarrowToUtf8(cx, dirName);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -174,7 +186,7 @@ JSString* ResolvePath(JSContext* cx, HandleString filenameStr,
|
|||
return str;
|
||||
}
|
||||
|
||||
UniqueChars filename = JS_EncodeStringToLatin1(cx, str);
|
||||
UniqueChars filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -220,15 +232,38 @@ JSString* ResolvePath(JSContext* cx, HandleString filenameStr,
|
|||
memcpy(result.get() + pathLen + 1, filename.get(), filenameLen);
|
||||
result[pathLen + 1 + filenameLen] = '\0';
|
||||
|
||||
return JS_NewStringCopyZ(cx, result.get());
|
||||
return JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(result.get(), resultLen));
|
||||
}
|
||||
|
||||
FILE* OpenFile(JSContext* cx, const char* filename, const char* mode) {
|
||||
FILE* file = fopen(filename, mode);
|
||||
#ifdef XP_WIN
|
||||
// Maximum valid mode string is "w+xb". Longer strings or strings
|
||||
// containing invalid input lead to undefined behavior.
|
||||
constexpr size_t MaxValidModeLength = 4;
|
||||
wchar_t wideMode[MaxValidModeLength + 1] = {0};
|
||||
for (size_t i = 0; i < MaxValidModeLength && mode[i] != '\0'; i++) {
|
||||
wideMode[i] = mode[i] & 0x7f;
|
||||
}
|
||||
|
||||
UniqueWideChars wideFilename = JS::EncodeUtf8ToWide(cx, filename);
|
||||
if (!wideFilename) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FILE* file = _wfopen(wideFilename.get(), wideMode);
|
||||
#else
|
||||
UniqueChars narrowFilename = JS::EncodeUtf8ToNarrow(cx, filename);
|
||||
if (!narrowFilename) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FILE* file = fopen(narrowFilename.get(), mode);
|
||||
#endif
|
||||
|
||||
if (!file) {
|
||||
if (UniqueChars error = SystemErrorMessage(cx, errno)) {
|
||||
JS_ReportErrorNumberLatin1(cx, my_GetErrorMessage, nullptr,
|
||||
JSSMSG_CANT_OPEN, filename, error.get());
|
||||
JS_ReportErrorNumberUTF8(cx, my_GetErrorMessage, nullptr,
|
||||
JSSMSG_CANT_OPEN, filename, error.get());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -241,11 +276,11 @@ bool ReadFile(JSContext* cx, const char* filename, FILE* file, char* buffer,
|
|||
if (cc != length) {
|
||||
if (ptrdiff_t(cc) < 0) {
|
||||
if (UniqueChars error = SystemErrorMessage(cx, errno)) {
|
||||
JS_ReportErrorNumberLatin1(cx, my_GetErrorMessage, nullptr,
|
||||
JSSMSG_CANT_READ, filename, error.get());
|
||||
JS_ReportErrorNumberUTF8(cx, my_GetErrorMessage, nullptr,
|
||||
JSSMSG_CANT_READ, filename, error.get());
|
||||
}
|
||||
} else {
|
||||
JS_ReportErrorLatin1(cx, "can't read %s: short read", filename);
|
||||
JS_ReportErrorUTF8(cx, "can't read %s: short read", filename);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -254,13 +289,13 @@ bool ReadFile(JSContext* cx, const char* filename, FILE* file, char* buffer,
|
|||
|
||||
bool FileSize(JSContext* cx, const char* filename, FILE* file, size_t* size) {
|
||||
if (fseek(file, 0, SEEK_END) != 0) {
|
||||
JS_ReportErrorLatin1(cx, "can't seek end of %s", filename);
|
||||
JS_ReportErrorUTF8(cx, "can't seek end of %s", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = ftell(file);
|
||||
if (fseek(file, 0, SEEK_SET) != 0) {
|
||||
JS_ReportErrorLatin1(cx, "can't seek start of %s", filename);
|
||||
JS_ReportErrorUTF8(cx, "can't seek start of %s", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -269,7 +304,7 @@ bool FileSize(JSContext* cx, const char* filename, FILE* file, size_t* size) {
|
|||
}
|
||||
|
||||
JSObject* FileAsTypedArray(JSContext* cx, JS::HandleString pathnameStr) {
|
||||
UniqueChars pathname = JS_EncodeStringToLatin1(cx, pathnameStr);
|
||||
UniqueChars pathname = JS_EncodeStringToUTF8(cx, pathnameStr);
|
||||
if (!pathname) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -307,10 +342,6 @@ JSObject* FileAsTypedArray(JSContext* cx, JS::HandleString pathnameStr) {
|
|||
// temporary buffer, read into that, and use a
|
||||
// race-safe primitive to copy memory into the
|
||||
// buffer.)
|
||||
pathname = JS_EncodeStringToUTF8(cx, pathnameStr);
|
||||
if (!pathname) {
|
||||
return nullptr;
|
||||
}
|
||||
JS_ReportErrorUTF8(cx, "can't read %s: shared memory buffer",
|
||||
pathname.get());
|
||||
return nullptr;
|
||||
|
@ -328,12 +359,21 @@ JSObject* FileAsTypedArray(JSContext* cx, JS::HandleString pathnameStr) {
|
|||
* Return the current working directory or |null| on failure.
|
||||
*/
|
||||
UniqueChars GetCWD(JSContext* cx) {
|
||||
#ifdef XP_WIN
|
||||
wchar_t buffer[PATH_MAX + 1];
|
||||
const wchar_t* cwd = _wgetcwd(buffer, PATH_MAX);
|
||||
if (!cwd) {
|
||||
return nullptr;
|
||||
}
|
||||
return JS::EncodeWideToUtf8(cx, buffer);
|
||||
#else
|
||||
char buffer[PATH_MAX + 1];
|
||||
const char* cwd = getcwd(buffer, PATH_MAX);
|
||||
if (!cwd) {
|
||||
return nullptr;
|
||||
}
|
||||
return js::DuplicateString(cx, buffer);
|
||||
return JS::EncodeNarrowToUtf8(cx, buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool ReadFile(JSContext* cx, unsigned argc, Value* vp,
|
||||
|
@ -417,7 +457,7 @@ static bool ListDir(JSContext* cx, unsigned argc, Value* vp,
|
|||
return false;
|
||||
}
|
||||
|
||||
UniqueChars pathname = JS_EncodeStringToLatin1(cx, str);
|
||||
UniqueChars pathname = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!pathname) {
|
||||
JS_ReportErrorASCII(cx, "os.file.listDir cannot convert path to Latin1");
|
||||
return false;
|
||||
|
@ -516,7 +556,7 @@ static bool osfile_writeTypedArrayToFile(JSContext* cx, unsigned argc,
|
|||
return false;
|
||||
}
|
||||
|
||||
UniqueChars filename = JS_EncodeStringToLatin1(cx, str);
|
||||
UniqueChars filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
@ -533,10 +573,6 @@ static bool osfile_writeTypedArrayToFile(JSContext* cx, unsigned argc,
|
|||
// Must opt in to use shared memory. For now, don't.
|
||||
//
|
||||
// See further comments in FileAsTypedArray, above.
|
||||
filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
JS_ReportErrorUTF8(cx, "can't write %s: shared memory buffer",
|
||||
filename.get());
|
||||
return false;
|
||||
|
@ -545,10 +581,6 @@ static bool osfile_writeTypedArrayToFile(JSContext* cx, unsigned argc,
|
|||
size_t length = obj->length();
|
||||
if (fwrite(buf, obj->bytesPerElement(), length, file) != length ||
|
||||
!autoClose.release()) {
|
||||
filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
JS_ReportErrorUTF8(cx, "can't write %s", filename.get());
|
||||
return false;
|
||||
}
|
||||
|
@ -657,7 +689,7 @@ static FileObject* redirect(JSContext* cx, HandleString relFilename,
|
|||
if (!filename) {
|
||||
return nullptr;
|
||||
}
|
||||
UniqueChars filenameABS = JS_EncodeStringToLatin1(cx, filename);
|
||||
UniqueChars filenameABS = JS_EncodeStringToUTF8(cx, filename);
|
||||
if (!filenameABS) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -852,6 +884,7 @@ static bool ospath_join(JSContext* cx, unsigned argc, Value* vp) {
|
|||
// e.g. the drive letter is always reset when an absolute path is appended.
|
||||
|
||||
JSStringBuilder buffer(cx);
|
||||
Rooted<JSLinearString*> str(cx);
|
||||
|
||||
for (unsigned i = 0; i < args.length(); i++) {
|
||||
if (!args[i].isString()) {
|
||||
|
@ -859,8 +892,7 @@ static bool ospath_join(JSContext* cx, unsigned argc, Value* vp) {
|
|||
return false;
|
||||
}
|
||||
|
||||
Rooted<JSLinearString*> str(cx,
|
||||
JS_EnsureLinearString(cx, args[i].toString()));
|
||||
str = JS_EnsureLinearString(cx, args[i].toString());
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
|
@ -868,7 +900,7 @@ static bool ospath_join(JSContext* cx, unsigned argc, Value* vp) {
|
|||
if (IsAbsolutePath(str)) {
|
||||
MOZ_ALWAYS_TRUE(buffer.resize(0));
|
||||
} else if (i != 0) {
|
||||
UniqueChars path = JS_EncodeStringToLatin1(cx, str);
|
||||
UniqueChars path = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
|
@ -959,21 +991,22 @@ inline char* strerror_message(char* result, char* buffer) { return result; }
|
|||
#endif
|
||||
|
||||
UniqueChars SystemErrorMessage(JSContext* cx, int errnum) {
|
||||
char buffer[200];
|
||||
|
||||
#if defined(XP_WIN)
|
||||
strerror_s(buffer, sizeof(buffer), errno);
|
||||
const char* errstr = buffer;
|
||||
wchar_t buffer[200];
|
||||
const wchar_t* errstr = buffer;
|
||||
if (_wcserror_s(buffer, mozilla::ArrayLength(buffer), errnum) != 0) {
|
||||
errstr = L"unknown error";
|
||||
}
|
||||
return JS::EncodeWideToUtf8(cx, errstr);
|
||||
#else
|
||||
const char* errstr =
|
||||
strerror_message(strerror_r(errno, buffer, sizeof(buffer)), buffer);
|
||||
#endif
|
||||
|
||||
char buffer[200];
|
||||
const char* errstr = strerror_message(
|
||||
strerror_r(errno, buffer, mozilla::ArrayLength(buffer)), buffer);
|
||||
if (!errstr) {
|
||||
errstr = "unknown error";
|
||||
}
|
||||
|
||||
return DuplicateString(cx, errstr);
|
||||
return JS::EncodeNarrowToUtf8(cx, errstr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __wasi__
|
||||
|
@ -981,7 +1014,7 @@ static void ReportSysError(JSContext* cx, const char* prefix) {
|
|||
MOZ_ASSERT(JS::StringIsASCII(prefix));
|
||||
|
||||
if (UniqueChars error = SystemErrorMessage(cx, errno)) {
|
||||
JS_ReportErrorLatin1(cx, "%s: %s", prefix, error.get());
|
||||
JS_ReportErrorUTF8(cx, "%s: %s", prefix, error.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,8 +41,7 @@ JSString* ResolvePath(JSContext* cx, JS::HandleString filenameStr,
|
|||
JSObject* FileAsTypedArray(JSContext* cx, JS::HandleString pathnameStr);
|
||||
|
||||
/**
|
||||
* Return the current working directory as a string encoded in the native file
|
||||
* system encoding.
|
||||
* Return the current working directory as a UTF-8 encoded string.
|
||||
*
|
||||
* @param cx current js-context
|
||||
* @return the working directory name or {@code nullptr} on error
|
||||
|
@ -53,7 +52,7 @@ JS::UniqueChars GetCWD(JSContext* cx);
|
|||
* Open the requested file.
|
||||
*
|
||||
* @param cx current js-context
|
||||
* @param filename file name encoded in the native file system encoding
|
||||
* @param filename file name encoded in UTF-8
|
||||
* @param mode file mode specifier, see {@code fopen} for valid values
|
||||
* @return a FILE pointer or {@code nullptr} on failure
|
||||
*/
|
||||
|
@ -63,8 +62,7 @@ FILE* OpenFile(JSContext* cx, const char* filename, const char* mode);
|
|||
* Read {@code length} bytes in the given buffer.
|
||||
*
|
||||
* @param cx current js-context
|
||||
* @param filename file name encoded in the native file system encoding, only
|
||||
* used for error reporting
|
||||
* @param filename file name encoded in UTF-8, only used for error reporting
|
||||
* @param file file pointer to read from
|
||||
* @param buffer destination buffer to copy read bytes into
|
||||
* @param length number of bytes to read
|
||||
|
@ -78,8 +76,7 @@ bool ReadFile(JSContext* cx, const char* filename, FILE* file, char* buffer,
|
|||
* Compute the file size in bytes.
|
||||
*
|
||||
* @param cx current js-context
|
||||
* @param filename file name encoded in the native file system encoding, only
|
||||
* used for error reporting
|
||||
* @param filename file name encoded in UTF-8, only used for error reporting
|
||||
* @param file file object to inspect
|
||||
* @param size output parameter to store the file size into
|
||||
* @return returns false and reports an error if an I/O error occurred
|
||||
|
@ -88,7 +85,7 @@ bool FileSize(JSContext* cx, const char* filename, FILE* file, size_t* size);
|
|||
|
||||
/**
|
||||
* Return the system error message for the given error number. The error
|
||||
* message is encoded in the system encoding.
|
||||
* message is UTF-8 encoded.
|
||||
*
|
||||
* @param cx current js-context
|
||||
* @param errnum error number
|
||||
|
|
|
@ -826,6 +826,10 @@ static bool TraceGrayRoots(JSTracer* trc, SliceBudget& budget, void* data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline JSString* NewStringCopyUTF8(JSContext* cx, const char* chars) {
|
||||
return JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(chars, strlen(chars)));
|
||||
}
|
||||
|
||||
static mozilla::UniqueFreePtr<char[]> GetLine(FILE* file, const char* prompt) {
|
||||
#ifdef EDITLINE
|
||||
/*
|
||||
|
@ -1011,7 +1015,7 @@ static bool RegisterScriptPathWithModuleLoader(JSContext* cx,
|
|||
// script's filename so that the module loader can use it to resolve
|
||||
// relative imports.
|
||||
|
||||
RootedString path(cx, JS_NewStringCopyZ(cx, filename));
|
||||
RootedString path(cx, NewStringCopyUTF8(cx, filename));
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1112,7 +1116,7 @@ enum class CompileUtf8 {
|
|||
bool compileOnly) {
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
|
||||
RootedString path(cx, JS_NewStringCopyZ(cx, filename));
|
||||
RootedString path(cx, NewStringCopyUTF8(cx, filename));
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1588,7 +1592,7 @@ static bool AddIntlExtras(JSContext* cx, unsigned argc, Value* vp) {
|
|||
if (!line) {
|
||||
if (errno) {
|
||||
if (UniqueChars error = SystemErrorMessage(cx, errno)) {
|
||||
JS_ReportErrorLatin1(cx, "%s", error.get());
|
||||
JS_ReportErrorUTF8(cx, "%s", error.get());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1776,11 +1780,12 @@ static bool CreateMappedArrayBuffer(JSContext* cx, unsigned argc, Value* vp) {
|
|||
// I need a file at a known location, and the only good way I know of to do
|
||||
// that right now is to include it in the repo alongside the test script.
|
||||
// Bug 944164 would introduce an alternative.
|
||||
JSString* filenameStr = ResolvePath(cx, rawFilenameStr, ScriptRelative);
|
||||
Rooted<JSString*> filenameStr(
|
||||
cx, ResolvePath(cx, rawFilenameStr, ScriptRelative));
|
||||
if (!filenameStr) {
|
||||
return false;
|
||||
}
|
||||
UniqueChars filename = JS_EncodeStringToLatin1(cx, filenameStr);
|
||||
UniqueChars filename = JS_EncodeStringToUTF8(cx, filenameStr);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1983,7 +1988,7 @@ static bool LoadScript(JSContext* cx, unsigned argc, Value* vp,
|
|||
return false;
|
||||
}
|
||||
|
||||
UniqueChars filename = JS_EncodeStringToLatin1(cx, str);
|
||||
UniqueChars filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2547,7 +2552,7 @@ static bool Evaluate(JSContext* cx, unsigned argc, Value* vp) {
|
|||
}
|
||||
|
||||
JSString* js::shell::FileAsString(JSContext* cx, JS::HandleString pathnameStr) {
|
||||
UniqueChars pathname = JS_EncodeStringToLatin1(cx, pathnameStr);
|
||||
UniqueChars pathname = JS_EncodeStringToUTF8(cx, pathnameStr);
|
||||
if (!pathname) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2590,10 +2595,6 @@ JSString* js::shell::FileAsString(JSContext* cx, JS::HandleString pathnameStr) {
|
|||
&len, js::MallocArena)
|
||||
.get());
|
||||
if (!ucbuf) {
|
||||
pathname = JS_EncodeStringToUTF8(cx, pathnameStr);
|
||||
if (!pathname) {
|
||||
return nullptr;
|
||||
}
|
||||
JS_ReportErrorUTF8(cx, "Invalid UTF-8 in file '%s'", pathname.get());
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2638,8 +2639,7 @@ static bool Run(JSContext* cx, unsigned argc, Value* vp) {
|
|||
RootedScript script(cx);
|
||||
int64_t startClock = PRMJ_Now();
|
||||
{
|
||||
/* FIXME: This should use UTF-8 (bug 987069). */
|
||||
UniqueChars filename = JS_EncodeStringToLatin1(cx, str);
|
||||
UniqueChars filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3319,11 +3319,12 @@ static bool DisassFile(JSContext* cx, unsigned argc, Value* vp) {
|
|||
}
|
||||
|
||||
// We should change DisassembleOptionParser to store CallArgs.
|
||||
JSString* str = JS::ToString(cx, HandleValue::fromMarkedLocation(&p.argv[0]));
|
||||
Rooted<JSString*> str(
|
||||
cx, JS::ToString(cx, HandleValue::fromMarkedLocation(&p.argv[0])));
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
UniqueChars filename = JS_EncodeStringToLatin1(cx, str);
|
||||
UniqueChars filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3402,8 +3403,7 @@ static bool DisassWithSrc(JSContext* cx, unsigned argc, Value* vp) {
|
|||
for (line1 = 0; line1 < line2 - 1; line1++) {
|
||||
char* tmp = fgets(linebuf, lineBufLen, file);
|
||||
if (!tmp) {
|
||||
/* FIXME: This should use UTF-8 (bug 987069). */
|
||||
JS_ReportErrorLatin1(cx, "failed to read %s fully", script->filename());
|
||||
JS_ReportErrorUTF8(cx, "failed to read %s fully", script->filename());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3428,13 +3428,8 @@ static bool DisassWithSrc(JSContext* cx, unsigned argc, Value* vp) {
|
|||
bupline = 0;
|
||||
while (line1 < line2) {
|
||||
if (!fgets(linebuf, lineBufLen, file)) {
|
||||
/*
|
||||
* FIXME: script->filename() should become UTF-8
|
||||
* (bug 987069).
|
||||
*/
|
||||
JS_ReportErrorNumberLatin1(cx, my_GetErrorMessage, nullptr,
|
||||
JSSMSG_UNEXPECTED_EOF,
|
||||
script->filename());
|
||||
JS_ReportErrorNumberUTF8(cx, my_GetErrorMessage, nullptr,
|
||||
JSSMSG_UNEXPECTED_EOF, script->filename());
|
||||
return false;
|
||||
}
|
||||
line1++;
|
||||
|
@ -4884,7 +4879,7 @@ static bool ParseModule(JSContext* cx, unsigned argc, Value* vp) {
|
|||
}
|
||||
|
||||
RootedString str(cx, args[1].toString());
|
||||
filename = JS_EncodeStringToLatin1(cx, str);
|
||||
filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
@ -6495,7 +6490,7 @@ static bool ThisFilename(JSContext* cx, unsigned argc, Value* vp) {
|
|||
return true;
|
||||
}
|
||||
|
||||
JSString* str = JS_NewStringCopyZ(cx, filename.get());
|
||||
JSString* str = NewStringCopyUTF8(cx, filename.get());
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
|
@ -6852,9 +6847,14 @@ class ShellSourceHook : public SourceHook {
|
|||
MOZ_ASSERT((twoByteSource != nullptr) != (utf8Source != nullptr),
|
||||
"must be called requesting only one of UTF-8 or UTF-16 source");
|
||||
|
||||
RootedString str(cx, JS_NewStringCopyZ(cx, filename));
|
||||
if (!str) {
|
||||
return false;
|
||||
RootedString str(cx);
|
||||
if (filename) {
|
||||
str = NewStringCopyUTF8(cx, filename);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
str = JS_GetEmptyString(cx);
|
||||
}
|
||||
RootedValue filenameValue(cx, StringValue(str));
|
||||
|
||||
|
@ -7656,24 +7656,6 @@ done:
|
|||
}
|
||||
}
|
||||
|
||||
static bool EnsureLatin1CharsLinearString(JSContext* cx, HandleValue value,
|
||||
UniqueChars* result) {
|
||||
if (!value.isString()) {
|
||||
result->reset(nullptr);
|
||||
return true;
|
||||
}
|
||||
RootedString str(cx, value.toString());
|
||||
if (!str->isLinear() || !str->hasLatin1Chars()) {
|
||||
JS_ReportErrorASCII(cx,
|
||||
"only latin1 chars and linear strings are expected");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use JS_EncodeStringToLatin1 to null-terminate.
|
||||
*result = JS_EncodeStringToLatin1(cx, str);
|
||||
return !!*result;
|
||||
}
|
||||
|
||||
static bool ConsumeBufferSource(JSContext* cx, JS::HandleObject obj,
|
||||
JS::MimeType, JS::StreamConsumer* consumer) {
|
||||
{
|
||||
|
@ -7682,8 +7664,12 @@ static bool ConsumeBufferSource(JSContext* cx, JS::HandleObject obj,
|
|||
return false;
|
||||
}
|
||||
UniqueChars urlChars;
|
||||
if (!EnsureLatin1CharsLinearString(cx, url, &urlChars)) {
|
||||
return false;
|
||||
if (url.isString()) {
|
||||
Rooted<JSString*> str(cx, url.toString());
|
||||
urlChars = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!urlChars) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RootedValue mapUrl(cx);
|
||||
|
@ -7691,8 +7677,12 @@ static bool ConsumeBufferSource(JSContext* cx, JS::HandleObject obj,
|
|||
return false;
|
||||
}
|
||||
UniqueChars mapUrlChars;
|
||||
if (!EnsureLatin1CharsLinearString(cx, mapUrl, &mapUrlChars)) {
|
||||
return false;
|
||||
if (mapUrl.isString()) {
|
||||
Rooted<JSString*> str(cx, mapUrl.toString());
|
||||
mapUrlChars = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!mapUrlChars) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
consumer->noteResponseURLs(urlChars.get(), mapUrlChars.get());
|
||||
|
@ -8075,7 +8065,7 @@ class ShellAutoEntryMonitor : JS::dbg::AutoEntryMonitor {
|
|||
|
||||
for (size_t i = 0; i < log.length(); i++) {
|
||||
char* name = log[i].get();
|
||||
RootedString string(cx, Atomize(cx, name, strlen(name)));
|
||||
RootedString string(cx, AtomizeUTF8Chars(cx, name, strlen(name)));
|
||||
if (!string) {
|
||||
return false;
|
||||
}
|
||||
|
@ -10494,8 +10484,11 @@ auto minVal(T a, Ts... args) {
|
|||
size_t minArgno = minVal(ppArgno, fpArgno, ufpArgno, ccArgno, mpArgno);
|
||||
|
||||
if (ppArgno == minArgno) {
|
||||
char* path = preludePaths.front();
|
||||
if (!Process(cx, path, false, PreludeScript)) {
|
||||
UniqueChars path = JS::EncodeNarrowToUtf8(cx, preludePaths.front());
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
if (!Process(cx, path.get(), false, PreludeScript)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -10504,8 +10497,11 @@ auto minVal(T a, Ts... args) {
|
|||
}
|
||||
|
||||
if (fpArgno == minArgno) {
|
||||
char* path = filePaths.front();
|
||||
if (!Process(cx, path, false, FileScript)) {
|
||||
UniqueChars path = JS::EncodeNarrowToUtf8(cx, filePaths.front());
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
if (!Process(cx, path.get(), false, FileScript)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -10514,8 +10510,11 @@ auto minVal(T a, Ts... args) {
|
|||
}
|
||||
|
||||
if (ufpArgno == minArgno) {
|
||||
char* path = utf16FilePaths.front();
|
||||
if (!Process(cx, path, false, FileScriptUtf16)) {
|
||||
UniqueChars path = JS::EncodeNarrowToUtf8(cx, utf16FilePaths.front());
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
if (!Process(cx, path.get(), false, FileScriptUtf16)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -10551,8 +10550,11 @@ auto minVal(T a, Ts... args) {
|
|||
|
||||
MOZ_ASSERT(mpArgno == minArgno);
|
||||
|
||||
char* path = modulePaths.front();
|
||||
if (!Process(cx, path, false, FileModule)) {
|
||||
UniqueChars path = JS::EncodeNarrowToUtf8(cx, modulePaths.front());
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
if (!Process(cx, path.get(), false, FileModule)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -10565,7 +10567,11 @@ auto minVal(T a, Ts... args) {
|
|||
|
||||
/* The |script| argument is processed after all options. */
|
||||
if (const char* path = op->getStringArg("script")) {
|
||||
if (!Process(cx, path, false, FileScript)) {
|
||||
UniqueChars pathUtf8 = JS::EncodeNarrowToUtf8(cx, path);
|
||||
if (!pathUtf8) {
|
||||
return false;
|
||||
}
|
||||
if (!Process(cx, pathUtf8.get(), false, FileScript)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -12553,25 +12559,32 @@ bool SetContextGCOptions(JSContext* cx, const OptionParser& op) {
|
|||
bool InitModuleLoader(JSContext* cx, const OptionParser& op) {
|
||||
RootedString moduleLoadPath(cx);
|
||||
if (const char* option = op.getStringOption("module-load-path")) {
|
||||
RootedString jspath(cx, JS_NewStringCopyZ(cx, option));
|
||||
UniqueChars pathUtf8 = JS::EncodeNarrowToUtf8(cx, option);
|
||||
if (!pathUtf8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<JSString*> jspath(cx, NewStringCopyUTF8(cx, pathUtf8.get()));
|
||||
if (!jspath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
moduleLoadPath = js::shell::ResolvePath(cx, jspath, RootRelative);
|
||||
|
||||
processWideModuleLoadPath = JS_EncodeStringToUTF8(cx, moduleLoadPath);
|
||||
if (!processWideModuleLoadPath) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
UniqueChars cwd = js::shell::GetCWD(cx);
|
||||
moduleLoadPath = JS_NewStringCopyZ(cx, cwd.get());
|
||||
}
|
||||
processWideModuleLoadPath = js::shell::GetCWD(cx);
|
||||
if (!processWideModuleLoadPath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!moduleLoadPath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
processWideModuleLoadPath = JS_EncodeStringToUTF8(cx, moduleLoadPath);
|
||||
if (!processWideModuleLoadPath) {
|
||||
MOZ_ASSERT(cx->isExceptionPending());
|
||||
return false;
|
||||
moduleLoadPath = NewStringCopyUTF8(cx, processWideModuleLoadPath.get());
|
||||
if (!moduleLoadPath) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
# include "js/Vector.h"
|
||||
#endif // __wasi__
|
||||
|
||||
#include "js/ErrorReport.h" // JS_ReportErrorNumberLatin1
|
||||
#include "js/CharacterEncoding.h" // EncodeUtf8ToWide, EncodeUtf8ToNarrow
|
||||
#include "js/ErrorReport.h" // JS_ReportErrorNumberUTF8
|
||||
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_CANT_OPEN
|
||||
|
||||
bool js::ReadCompleteFile(JSContext* cx, FILE* fp, FileContents& buffer) {
|
||||
|
@ -103,6 +104,22 @@ static bool NormalizeWASIPath(const char* filename,
|
|||
}
|
||||
#endif
|
||||
|
||||
static FILE* OpenFile(JSContext* cx, const char* filename) {
|
||||
#ifdef XP_WIN
|
||||
JS::UniqueWideChars wideFilename = JS::EncodeUtf8ToWide(cx, filename);
|
||||
if (!wideFilename) {
|
||||
return nullptr;
|
||||
}
|
||||
return _wfopen(wideFilename.get(), L"r");
|
||||
#else
|
||||
JS::UniqueChars narrowFilename = JS::EncodeUtf8ToNarrow(cx, filename);
|
||||
if (!narrowFilename) {
|
||||
return nullptr;
|
||||
}
|
||||
return fopen(narrowFilename.get(), "r");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a source file for reading. Supports "-" and nullptr to mean stdin. The
|
||||
* return value must be fclosed unless it is stdin.
|
||||
|
@ -116,17 +133,13 @@ bool js::AutoFile::open(JSContext* cx, const char* filename) {
|
|||
if (!NormalizeWASIPath(filename, &normalized, cx)) {
|
||||
return false;
|
||||
}
|
||||
fp_ = fopen(normalized.begin(), "r");
|
||||
fp_ = OpenFile(cx, normalized.begin());
|
||||
#else
|
||||
fp_ = fopen(filename, "r");
|
||||
fp_ = OpenFile(cx, filename);
|
||||
#endif
|
||||
if (!fp_) {
|
||||
/*
|
||||
* Use Latin1 variant here because the encoding of filename is
|
||||
* platform dependent.
|
||||
*/
|
||||
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_CANT_OPEN,
|
||||
filename, "No such file or directory");
|
||||
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_CANT_OPEN,
|
||||
filename, "No such file or directory");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2735,11 +2735,17 @@ JSString* JS::GetPCCountScriptSummary(JSContext* cx, size_t index) {
|
|||
|
||||
json.beginObject();
|
||||
|
||||
RootedString filename(cx, NewStringCopyZ<CanGC>(cx, script->filename()));
|
||||
if (!filename) {
|
||||
Rooted<JSString*> filenameStr(cx);
|
||||
if (const char* filename = script->filename()) {
|
||||
filenameStr =
|
||||
JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(filename, strlen(filename)));
|
||||
} else {
|
||||
filenameStr = JS_GetEmptyString(cx);
|
||||
}
|
||||
if (!filenameStr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!JSONStringProperty(sp, json, "file", filename)) {
|
||||
if (!JSONStringProperty(sp, json, "file", filenameStr)) {
|
||||
return nullptr;
|
||||
}
|
||||
json.property("line", script->lineno());
|
||||
|
|
|
@ -61,7 +61,7 @@ using namespace js;
|
|||
|
||||
#define IMPLEMENT_ERROR_PROTO_CLASS(name) \
|
||||
{ \
|
||||
# name ".prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_##name), \
|
||||
#name ".prototype", JSCLASS_HAS_CACHED_PROTO(JSProto_##name), \
|
||||
JS_NULL_CLASS_OPS, \
|
||||
&ErrorObject::classSpecs[JSProto_##name - JSProto_Error] \
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ const ClassSpec ErrorObject::classSpecs[JSEXN_ERROR_LIMIT] = {
|
|||
|
||||
#define IMPLEMENT_ERROR_CLASS_CORE(name, reserved_slots) \
|
||||
{ \
|
||||
# name, \
|
||||
#name, \
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_##name) | \
|
||||
JSCLASS_HAS_RESERVED_SLOTS(reserved_slots) | \
|
||||
JSCLASS_BACKGROUND_FINALIZE, \
|
||||
|
@ -247,7 +247,8 @@ static ErrorObject* CreateErrorObject(JSContext* cx, const CallArgs& args,
|
|||
fileName = cx->runtime()->emptyString;
|
||||
if (!iter.done()) {
|
||||
if (const char* cfilename = iter.filename()) {
|
||||
fileName = JS_NewStringCopyZ(cx, cfilename);
|
||||
fileName = JS_NewStringCopyUTF8Z(
|
||||
cx, JS::ConstUTF8CharsZ(cfilename, strlen(cfilename)));
|
||||
}
|
||||
if (iter.hasScript()) {
|
||||
sourceId = iter.script()->scriptSource()->id();
|
||||
|
@ -571,7 +572,8 @@ JSErrorReport* js::ErrorObject::getOrCreateErrorReport(JSContext* cx) {
|
|||
report.exnType = type_;
|
||||
|
||||
// Filename.
|
||||
UniqueChars filenameStr = JS_EncodeStringToLatin1(cx, fileName(cx));
|
||||
RootedString filename(cx, fileName(cx));
|
||||
UniqueChars filenameStr = JS_EncodeStringToUTF8(cx, filename);
|
||||
if (!filenameStr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -696,8 +696,9 @@ JSObject* js::CreateErrorNotesArray(JSContext* cx, JSErrorReport* report) {
|
|||
}
|
||||
|
||||
RootedValue filenameVal(cx);
|
||||
if (note->filename) {
|
||||
RootedString filenameStr(cx, NewStringCopyZ<CanGC>(cx, note->filename));
|
||||
if (const char* filename = note->filename) {
|
||||
JS::UTF8Chars utf8chars(filename, strlen(filename));
|
||||
Rooted<JSString*> filenameStr(cx, NewStringCopyUTF8N(cx, utf8chars));
|
||||
if (!filenameStr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
#include "vm/StringType.h" // JSString, JSAtom
|
||||
#include "vm/Time.h" // AutoIncrementalTimer
|
||||
#include "vm/ToSource.h" // JS::ValueToSource
|
||||
#include "vm/Warnings.h" // js::WarnNumberLatin1
|
||||
#ifdef MOZ_VTUNE
|
||||
# include "vtune/VTuneWrapper.h"
|
||||
#endif
|
||||
|
|
|
@ -554,7 +554,7 @@ class ScriptSource {
|
|||
};
|
||||
ExclusiveData<ReaderInstances> readers_;
|
||||
|
||||
// The filename of this script.
|
||||
// The UTF-8 encoded filename of this script.
|
||||
SharedImmutableString filename_;
|
||||
|
||||
// Hash of the script filename;
|
||||
|
@ -569,7 +569,7 @@ class ScriptSource {
|
|||
// raw filename of "foo.js".
|
||||
//
|
||||
// In the case described above, this field will be set to to the original raw
|
||||
// filename from above, otherwise it will be mozilla::Nothing.
|
||||
// UTF-8 encoded filename from above, otherwise it will be mozilla::Nothing.
|
||||
SharedImmutableString introducerFilename_;
|
||||
|
||||
SharedImmutableTwoByteString displayURL_;
|
||||
|
|
|
@ -36,6 +36,8 @@ static const char* FunctionName(JSContext* cx, JSFunction* fun,
|
|||
if (!fun->displayAtom()) {
|
||||
return probes::anonymousName;
|
||||
}
|
||||
// TODO: Should be JS_EncodeStringToUTF8, but that'd introduce a rooting
|
||||
// hazard, because JS_EncodeStringToUTF8 can GC.
|
||||
*bytes = JS_EncodeStringToLatin1(cx, fun->displayAtom());
|
||||
return *bytes ? bytes->get() : probes::nullName;
|
||||
}
|
||||
|
|
|
@ -1835,7 +1835,7 @@ bool SavedStacks::getLocation(JSContext* cx, const FrameIter& iter,
|
|||
locationp.setSource(AtomizeChars(cx, displayURL, js_strlen(displayURL)));
|
||||
} else {
|
||||
const char* filename = iter.filename() ? iter.filename() : "";
|
||||
locationp.setSource(Atomize(cx, filename, strlen(filename)));
|
||||
locationp.setSource(AtomizeUTF8Chars(cx, filename, strlen(filename)));
|
||||
}
|
||||
if (!locationp.source()) {
|
||||
return false;
|
||||
|
@ -1851,8 +1851,7 @@ bool SavedStacks::getLocation(JSContext* cx, const FrameIter& iter,
|
|||
RootedScript script(cx, iter.script());
|
||||
jsbytecode* pc = iter.pc();
|
||||
|
||||
PCKey key(script, pc);
|
||||
PCLocationMap::AddPtr p = pcLocationMap.lookupForAdd(key);
|
||||
PCLocationMap::AddPtr p = pcLocationMap.lookupForAdd(PCKey(script, pc));
|
||||
|
||||
if (!p) {
|
||||
Rooted<JSAtom*> source(cx);
|
||||
|
@ -1860,7 +1859,7 @@ bool SavedStacks::getLocation(JSContext* cx, const FrameIter& iter,
|
|||
source = AtomizeChars(cx, displayURL, js_strlen(displayURL));
|
||||
} else {
|
||||
const char* filename = script->filename() ? script->filename() : "";
|
||||
source = Atomize(cx, filename, strlen(filename));
|
||||
source = AtomizeUTF8Chars(cx, filename, strlen(filename));
|
||||
}
|
||||
if (!source) {
|
||||
return false;
|
||||
|
@ -1871,6 +1870,7 @@ bool SavedStacks::getLocation(JSContext* cx, const FrameIter& iter,
|
|||
uint32_t line = PCToLineNumber(script, pc, &column);
|
||||
|
||||
// Make the column 1-based. See comment above.
|
||||
PCKey key(script, pc);
|
||||
LocationValue value(source, sourceId, line, column + 1);
|
||||
if (!pcLocationMap.add(p, key, value)) {
|
||||
ReportOutOfMemory(cx);
|
||||
|
|
|
@ -340,7 +340,7 @@ using CStringCountMap = HashMap<const char*, CountBasePtr,
|
|||
// `Map` must be a `HashMap` from some key type to a `CountBasePtr`.
|
||||
//
|
||||
// `GetName` must be a callable type which takes `const Map::Key&` and returns
|
||||
// `const char*`.
|
||||
// `JSAtom*`.
|
||||
template <class Map, class GetName>
|
||||
static PlainObject* countMapToObject(JSContext* cx, Map& map, GetName getName) {
|
||||
// Build a vector of pointers to entries; sort by total; and then use
|
||||
|
@ -374,59 +374,7 @@ static PlainObject* countMapToObject(JSContext* cx, Map& map, GetName getName) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const char* name = getName(entry->key());
|
||||
MOZ_ASSERT(name);
|
||||
JSAtom* atom = Atomize(cx, name, strlen(name));
|
||||
if (!atom) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RootedId entryId(cx, AtomToId(atom));
|
||||
if (!DefineDataProperty(cx, obj, entryId, thenReport)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
template <class Map, class GetName>
|
||||
static PlainObject* countMap16ToObject(JSContext* cx, Map& map,
|
||||
GetName getName) {
|
||||
// Build a vector of pointers to entries; sort by total; and then use
|
||||
// that to build the result object. This makes the ordering of entries
|
||||
// more interesting, and a little less non-deterministic.
|
||||
|
||||
JS::ubi::Vector<typename Map::Entry*> entries;
|
||||
if (!entries.reserve(map.count())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto r = map.all(); !r.empty(); r.popFront()) {
|
||||
entries.infallibleAppend(&r.front());
|
||||
}
|
||||
|
||||
if (entries.length()) {
|
||||
qsort(entries.begin(), entries.length(), sizeof(*entries.begin()),
|
||||
compareEntries<typename Map::Entry>);
|
||||
}
|
||||
|
||||
Rooted<PlainObject*> obj(cx, NewPlainObject(cx));
|
||||
if (!obj) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto& entry : entries) {
|
||||
CountBasePtr& thenCount = entry->value();
|
||||
RootedValue thenReport(cx);
|
||||
if (!thenCount->report(cx, &thenReport)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char16_t* name = getName(entry->key());
|
||||
MOZ_ASSERT(name);
|
||||
JSAtom* atom = AtomizeChars(cx, name, js_strlen(name));
|
||||
JSAtom* atom = getName(entry->key());
|
||||
if (!atom) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -528,8 +476,10 @@ bool ByObjectClass::report(JSContext* cx, CountBase& countBase,
|
|||
Count& count = static_cast<Count&>(countBase);
|
||||
|
||||
Rooted<PlainObject*> obj(
|
||||
cx,
|
||||
countMapToObject(cx, count.table, [](const char* key) { return key; }));
|
||||
cx, countMapToObject(cx, count.table, [cx](const char* key) {
|
||||
MOZ_ASSERT(key);
|
||||
return Atomize(cx, key, strlen(key));
|
||||
}));
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
@ -636,8 +586,10 @@ bool ByDomObjectClass::report(JSContext* cx, CountBase& countBase,
|
|||
Count& count = static_cast<Count&>(countBase);
|
||||
|
||||
Rooted<PlainObject*> obj(
|
||||
cx, countMap16ToObject(cx, count.table, [](const UniqueC16String& key) {
|
||||
return key.get();
|
||||
cx, countMapToObject(cx, count.table, [cx](const UniqueC16String& key) {
|
||||
const char16_t* chars = key.get();
|
||||
MOZ_ASSERT(chars);
|
||||
return AtomizeChars(cx, chars, js_strlen(chars));
|
||||
}));
|
||||
if (!obj) {
|
||||
return false;
|
||||
|
@ -1064,8 +1016,10 @@ bool ByFilename::report(JSContext* cx, CountBase& countBase,
|
|||
Count& count = static_cast<Count&>(countBase);
|
||||
|
||||
Rooted<PlainObject*> obj(
|
||||
cx, countMapToObject(cx, count.table,
|
||||
[](const UniqueCString& key) { return key.get(); }));
|
||||
cx, countMapToObject(cx, count.table, [cx](const UniqueCString& key) {
|
||||
const char* utf8chars = key.get();
|
||||
return AtomizeUTF8Chars(cx, utf8chars, strlen(utf8chars));
|
||||
}));
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ struct FeatureArgs {
|
|||
// Describes the JS scripted caller of a request to compile a wasm module.
|
||||
|
||||
struct ScriptedCaller {
|
||||
UniqueChars filename;
|
||||
UniqueChars filename; // UTF-8 encoded
|
||||
bool filenameIsURL;
|
||||
unsigned line;
|
||||
|
||||
|
|
|
@ -2606,7 +2606,8 @@ JSString* Instance::createDisplayURL(JSContext* cx) {
|
|||
// fetched Response.
|
||||
|
||||
if (metadata().filenameIsURL) {
|
||||
return NewStringCopyZ<CanGC>(cx, metadata().filename.get());
|
||||
const char* filename = metadata().filename.get();
|
||||
return NewStringCopyUTF8N(cx, JS::UTF8Chars(filename, strlen(filename)));
|
||||
}
|
||||
|
||||
// Otherwise, build wasm module URL from following parts:
|
||||
|
|
|
@ -4455,9 +4455,14 @@ static bool Reject(JSContext* cx, const CompileArgs& args,
|
|||
}
|
||||
|
||||
RootedObject stack(cx, promise->allocationSite());
|
||||
RootedString filename(
|
||||
cx, JS_NewStringCopyZ(cx, args.scriptedCaller.filename.get()));
|
||||
if (!filename) {
|
||||
RootedString fileName(cx);
|
||||
if (const char* filename = args.scriptedCaller.filename.get()) {
|
||||
fileName =
|
||||
JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(filename, strlen(filename)));
|
||||
} else {
|
||||
fileName = JS_GetEmptyString(cx);
|
||||
}
|
||||
if (!fileName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4481,7 +4486,7 @@ static bool Reject(JSContext* cx, const CompileArgs& args,
|
|||
auto cause = JS::NothingHandleValue;
|
||||
|
||||
RootedObject errorObj(
|
||||
cx, ErrorObject::create(cx, JSEXN_WASMCOMPILEERROR, stack, filename, 0,
|
||||
cx, ErrorObject::create(cx, JSEXN_WASMCOMPILEERROR, stack, fileName, 0,
|
||||
line, 0, nullptr, message, cause));
|
||||
if (!errorObj) {
|
||||
return false;
|
||||
|
|
|
@ -1159,7 +1159,7 @@ static nsresult JSErrorToXPCException(JSContext* cx, const char* toStringResult,
|
|||
|
||||
data = new nsScriptError();
|
||||
data->nsIScriptError::InitWithWindowID(
|
||||
bestMessage, NS_ConvertASCIItoUTF16(report->filename),
|
||||
bestMessage, NS_ConvertUTF8toUTF16(report->filename),
|
||||
linebuf ? nsDependentString(linebuf, report->linebufLength())
|
||||
: EmptyString(),
|
||||
report->lineno, report->tokenOffset(), flags, "XPConnect JavaScript"_ns,
|
||||
|
|
|
@ -164,32 +164,7 @@ static bool GetLocationProperty(JSContext* cx, unsigned argc, Value* vp) {
|
|||
#else
|
||||
JS::AutoFilename filename;
|
||||
if (JS::DescribeScriptedCaller(cx, &filename) && filename.get()) {
|
||||
# if defined(XP_WIN)
|
||||
// convert from the system codepage to UTF-16
|
||||
int bufferSize =
|
||||
MultiByteToWideChar(CP_ACP, 0, filename.get(), -1, nullptr, 0);
|
||||
nsAutoString filenameString;
|
||||
filenameString.SetLength(bufferSize);
|
||||
MultiByteToWideChar(CP_ACP, 0, filename.get(), -1,
|
||||
(LPWSTR)filenameString.BeginWriting(),
|
||||
filenameString.Length());
|
||||
// remove the null terminator
|
||||
filenameString.SetLength(bufferSize - 1);
|
||||
|
||||
// replace forward slashes with backslashes,
|
||||
// since nsLocalFileWin chokes on them
|
||||
char16_t* start = filenameString.BeginWriting();
|
||||
char16_t* end = filenameString.EndWriting();
|
||||
|
||||
while (start != end) {
|
||||
if (*start == L'/') {
|
||||
*start = L'\\';
|
||||
}
|
||||
start++;
|
||||
}
|
||||
# elif defined(XP_UNIX)
|
||||
NS_ConvertUTF8toUTF16 filenameString(filename.get());
|
||||
# endif
|
||||
|
||||
nsCOMPtr<nsIFile> location;
|
||||
nsresult rv =
|
||||
|
@ -375,7 +350,7 @@ static bool Load(JSContext* cx, unsigned argc, Value* vp) {
|
|||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
JS::UniqueChars filename = JS_EncodeStringToLatin1(cx, str);
|
||||
JS::UniqueChars filename = JS_EncodeStringToUTF8(cx, str);
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
@ -791,10 +766,15 @@ static bool ProcessFile(AutoJSAPI& jsapi, const char* filename, FILE* file,
|
|||
}
|
||||
ungetc(ch, file);
|
||||
|
||||
JS::UniqueChars filenameUtf8 = JS::EncodeNarrowToUtf8(jsapi.cx(), filename);
|
||||
if (!filenameUtf8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::RootedScript script(cx);
|
||||
JS::RootedValue unused(cx);
|
||||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(filename, 1)
|
||||
options.setFileAndLine(filenameUtf8.get(), 1)
|
||||
.setIsRunOnce(true)
|
||||
.setNoScriptRval(true)
|
||||
.setSkipFilenameValidation(true);
|
||||
|
|
Загрузка…
Ссылка в новой задаче