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:
André Bargull 2023-05-22 12:28:15 +00:00
Родитель 5c1fd21f5e
Коммит e56b840bda
33 изменённых файлов: 313 добавлений и 291 удалений

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

@ -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);