forked from mirrors/gecko-dev
Backed out changeset 4e2a9894fb4c (bug 1772932) for causing bc failures on browser_addon_list_reordering.js. CLOSED TREE
This commit is contained in:
parent
9258abc05d
commit
09f8e5b108
21 changed files with 172 additions and 143 deletions
|
|
@ -1842,11 +1842,9 @@ class SchemaAPIManager extends EventEmitter {
|
|||
ExtensionAPI,
|
||||
ExtensionAPIPersistent,
|
||||
ExtensionCommon,
|
||||
IOUtils,
|
||||
MatchGlob,
|
||||
MatchPattern,
|
||||
MatchPatternSet,
|
||||
PathUtils,
|
||||
Services,
|
||||
StructuredCloneHolder,
|
||||
WebExtensionPolicy,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ ChromeUtils.defineModuleGetter(
|
|||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
JSONFile: "resource://gre/modules/JSONFile.sys.mjs",
|
||||
});
|
||||
ChromeUtils.defineModuleGetter(lazy, "OS", "resource://gre/modules/osfile.jsm");
|
||||
|
||||
function isStructuredCloneHolder(value) {
|
||||
return (
|
||||
|
|
@ -104,7 +105,10 @@ var ExtensionStorage = {
|
|||
* @returns {Promise<JSONFile>}
|
||||
*/
|
||||
async _readFile(extensionId) {
|
||||
await IOUtils.makeDirectory(this.getExtensionDir(extensionId));
|
||||
lazy.OS.File.makeDir(this.getExtensionDir(extensionId), {
|
||||
ignoreExisting: true,
|
||||
from: lazy.OS.Constants.Path.profileDir,
|
||||
});
|
||||
|
||||
let jsonFile = new lazy.JSONFile({
|
||||
path: this.getStorageFile(extensionId),
|
||||
|
|
@ -182,7 +186,7 @@ var ExtensionStorage = {
|
|||
* @returns {string}
|
||||
*/
|
||||
getExtensionDir(extensionId) {
|
||||
return PathUtils.join(this.extensionDir, extensionId);
|
||||
return lazy.OS.Path.join(this.extensionDir, extensionId);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -194,7 +198,7 @@ var ExtensionStorage = {
|
|||
* @returns {string}
|
||||
*/
|
||||
getStorageFile(extensionId) {
|
||||
return PathUtils.join(this.extensionDir, extensionId, "storage.js");
|
||||
return lazy.OS.Path.join(this.extensionDir, extensionId, "storage.js");
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -446,7 +450,7 @@ var ExtensionStorage = {
|
|||
};
|
||||
|
||||
XPCOMUtils.defineLazyGetter(ExtensionStorage, "extensionDir", () =>
|
||||
PathUtils.join(PathUtils.profileDir, "browser-extension-data")
|
||||
lazy.OS.Path.join(lazy.OS.Constants.Path.profileDir, "browser-extension-data")
|
||||
);
|
||||
|
||||
ExtensionStorage.init();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
|
|||
ExtensionStorage: "resource://gre/modules/ExtensionStorage.jsm",
|
||||
ExtensionUtils: "resource://gre/modules/ExtensionUtils.jsm",
|
||||
getTrimmedString: "resource://gre/modules/ExtensionTelemetry.jsm",
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
});
|
||||
|
||||
// The userContextID reserved for the extension storage (its purpose is ensuring that the IndexedDB
|
||||
|
|
@ -460,15 +461,17 @@ async function migrateJSONFileData(extension, storagePrincipal) {
|
|||
abortIfShuttingDown();
|
||||
|
||||
oldStoragePath = lazy.ExtensionStorage.getStorageFile(extension.id);
|
||||
oldStorageExists = await IOUtils.exists(oldStoragePath).catch(fileErr => {
|
||||
// If we can't access the oldStoragePath here, then extension is also going to be unable to
|
||||
// access it, and so we log the error but we don't stop the extension from switching to
|
||||
// the IndexedDB backend.
|
||||
extension.logWarning(
|
||||
`Unable to access extension storage.local data file: ${fileErr.message}::${fileErr.stack}`
|
||||
);
|
||||
return false;
|
||||
});
|
||||
oldStorageExists = await lazy.OS.File.exists(oldStoragePath).catch(
|
||||
fileErr => {
|
||||
// If we can't access the oldStoragePath here, then extension is also going to be unable to
|
||||
// access it, and so we log the error but we don't stop the extension from switching to
|
||||
// the IndexedDB backend.
|
||||
extension.logWarning(
|
||||
`Unable to access extension storage.local data file: ${fileErr.message}::${fileErr.stack}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
// Migrate any data stored in the JSONFile backend (if any), and remove the old data file
|
||||
// if the migration has been completed successfully.
|
||||
|
|
@ -542,12 +545,15 @@ async function migrateJSONFileData(extension, storagePrincipal) {
|
|||
try {
|
||||
// Only migrate the file when it actually exists (e.g. the file name is not going to exist
|
||||
// when it is corrupted, because JSONFile internally rename it to `.corrupt`.
|
||||
if (await IOUtils.exists(oldStoragePath)) {
|
||||
const uniquePath = await IOUtils.createUniqueFile(
|
||||
PathUtils.parent(oldStoragePath),
|
||||
`${PathUtils.filename(oldStoragePath)}.migrated`
|
||||
if (await lazy.OS.File.exists(oldStoragePath)) {
|
||||
let openInfo = await lazy.OS.File.openUnique(
|
||||
`${oldStoragePath}.migrated`,
|
||||
{
|
||||
humanReadable: true,
|
||||
}
|
||||
);
|
||||
await IOUtils.move(oldStoragePath, uniquePath);
|
||||
await openInfo.file.close();
|
||||
await lazy.OS.File.move(oldStoragePath, openInfo.path);
|
||||
}
|
||||
} catch (err) {
|
||||
nonFatalError = err;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ ChromeUtils.defineModuleGetter(
|
|||
"ExtensionPermissions",
|
||||
"resource://gre/modules/ExtensionPermissions.jsm"
|
||||
);
|
||||
ChromeUtils.defineModuleGetter(lazy, "OS", "resource://gre/modules/osfile.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(
|
||||
lazy,
|
||||
"apiManager",
|
||||
|
|
@ -214,7 +216,7 @@ class MockExtension {
|
|||
});
|
||||
})
|
||||
.then(() => {
|
||||
return IOUtils.remove(this.file.path);
|
||||
return lazy.OS.File.remove(this.file.path);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
|||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(lazy, {
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
Schemas: "resource://gre/modules/Schemas.jsm",
|
||||
});
|
||||
|
||||
|
|
@ -99,7 +100,7 @@ var NativeManifests = {
|
|||
|
||||
_tryPath(type, path, name, context, logIfNotFound) {
|
||||
return Promise.resolve()
|
||||
.then(() => IOUtils.readUTF8(path))
|
||||
.then(() => lazy.OS.File.read(path, { encoding: "utf-8" }))
|
||||
.then(data => {
|
||||
let manifest;
|
||||
try {
|
||||
|
|
@ -147,7 +148,7 @@ var NativeManifests = {
|
|||
return manifest;
|
||||
})
|
||||
.catch(ex => {
|
||||
if (DOMException.isInstance(ex) && ex.name == "NotFoundError") {
|
||||
if (ex instanceof lazy.OS.File.Error && ex.becauseNoSuchFile) {
|
||||
if (logIfNotFound) {
|
||||
Cu.reportError(
|
||||
`Error reading native manifest file ${path}: file is referenced in the registry but does not exist`
|
||||
|
|
@ -161,7 +162,7 @@ var NativeManifests = {
|
|||
|
||||
async _tryPaths(type, name, dirs, context) {
|
||||
for (let dir of dirs) {
|
||||
let path = PathUtils.join(dir, TYPES[type], `${name}.json`);
|
||||
let path = lazy.OS.Path.join(dir, TYPES[type], `${name}.json`);
|
||||
let manifest = await this._tryPath(type, path, name, context, false);
|
||||
if (manifest) {
|
||||
return { path, manifest };
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetters(lazy, {
|
||||
NativeManifests: "resource://gre/modules/NativeManifests.jsm",
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
});
|
||||
|
||||
// For a graceful shutdown (i.e., when the extension is unloaded or when it
|
||||
|
|
@ -88,26 +89,21 @@ var NativeApp = class extends EventEmitter {
|
|||
|
||||
let command = hostInfo.manifest.path;
|
||||
if (AppConstants.platform == "win") {
|
||||
// OS.Path.join() ignores anything before the last absolute path
|
||||
// it sees, so if command is already absolute, it remains unchanged
|
||||
// here. If it is relative, we get the proper absolute path here.
|
||||
command = lazy.OS.Path.join(
|
||||
lazy.OS.Path.dirname(hostInfo.path),
|
||||
command
|
||||
);
|
||||
// Normalize in case the extension used / instead of \.
|
||||
command = command.replaceAll("/", "\\");
|
||||
|
||||
if (!PathUtils.isAbsolute(command)) {
|
||||
const parentPath = PathUtils.parent(
|
||||
hostInfo.path.replaceAll("/", "\\")
|
||||
);
|
||||
command = PathUtils.joinRelative(parentPath, command);
|
||||
}
|
||||
} else if (!PathUtils.isAbsolute(command)) {
|
||||
// Only windows supports relative paths.
|
||||
throw new Error(
|
||||
"NativeApp requires absolute path to command on this platform"
|
||||
);
|
||||
}
|
||||
|
||||
let subprocessOpts = {
|
||||
command: command,
|
||||
arguments: [hostInfo.path, context.extension.id],
|
||||
workdir: PathUtils.parent(command),
|
||||
workdir: lazy.OS.Path.dirname(command),
|
||||
stderr: "pipe",
|
||||
disclaim: true,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ ChromeUtils.defineESModuleGetters(this, {
|
|||
Downloads: "resource://gre/modules/Downloads.sys.mjs",
|
||||
FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
|
||||
});
|
||||
ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"DownloadLastDir",
|
||||
|
|
@ -668,26 +669,21 @@ this.downloads = class extends ExtensionAPIPersistent {
|
|||
return Promise.reject({ message: "filename must not be empty" });
|
||||
}
|
||||
|
||||
if (PathUtils.isAbsolute(filename)) {
|
||||
let path = OS.Path.split(filename);
|
||||
if (path.absolute) {
|
||||
return Promise.reject({
|
||||
message: "filename must not be an absolute path",
|
||||
});
|
||||
}
|
||||
|
||||
const pathComponents = PathUtils.splitRelative(filename, {
|
||||
allowEmpty: true,
|
||||
allowCurrentDir: true,
|
||||
allowParentDir: true,
|
||||
});
|
||||
|
||||
if (pathComponents.some(component => component == "..")) {
|
||||
if (path.components.some(component => component == "..")) {
|
||||
return Promise.reject({
|
||||
message: "filename must not contain back-references (..)",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
pathComponents.some(component => {
|
||||
path.components.some(component => {
|
||||
let sanitized = DownloadPaths.sanitize(component, {
|
||||
compressWhitespaces: false,
|
||||
});
|
||||
|
|
@ -830,10 +826,7 @@ this.downloads = class extends ExtensionAPIPersistent {
|
|||
}
|
||||
}
|
||||
|
||||
let target = PathUtils.joinRelative(
|
||||
downloadsDir,
|
||||
filename || "download"
|
||||
);
|
||||
let target = OS.Path.join(downloadsDir, filename || "download");
|
||||
|
||||
let saveAs;
|
||||
if (options.saveAs !== null) {
|
||||
|
|
@ -850,10 +843,10 @@ this.downloads = class extends ExtensionAPIPersistent {
|
|||
}
|
||||
|
||||
// Create any needed subdirectories if required by filename.
|
||||
const dir = PathUtils.parent(target);
|
||||
await IOUtils.makeDirectory(dir);
|
||||
const dir = OS.Path.dirname(target);
|
||||
await OS.File.makeDir(dir, { from: downloadsDir });
|
||||
|
||||
if (await IOUtils.exists(target)) {
|
||||
if (await OS.File.exists(target)) {
|
||||
// This has a race, something else could come along and create
|
||||
// the file between this test and them time the download code
|
||||
// creates the target file. But we can't easily fix it without
|
||||
|
|
@ -867,7 +860,7 @@ this.downloads = class extends ExtensionAPIPersistent {
|
|||
if (saveAs) {
|
||||
// createNiceUniqueFile actually creates the file, which
|
||||
// is premature if we need to show a SaveAs dialog.
|
||||
await IOUtils.remove(target);
|
||||
await OS.File.remove(target);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -922,7 +915,7 @@ this.downloads = class extends ExtensionAPIPersistent {
|
|||
// so that this doesn't break where navigator:browser isn't the
|
||||
// main window (e.g. Thunderbird).
|
||||
const window = global.windowTracker.getTopWindow().window;
|
||||
const basename = PathUtils.filename(target);
|
||||
const basename = OS.Path.basename(target);
|
||||
const ext = basename.match(/\.([^.]+)$/)?.[1];
|
||||
|
||||
// If the filename passed in by the extension is a simple name
|
||||
|
|
@ -1061,12 +1054,9 @@ this.downloads = class extends ExtensionAPIPersistent {
|
|||
message: `Cannot remove incomplete download id ${id}`,
|
||||
});
|
||||
}
|
||||
return IOUtils.remove(item.filename, { ignoreAbsent: false }).catch(
|
||||
return OS.File.remove(item.filename, { ignoreAbsent: false }).catch(
|
||||
err => {
|
||||
if (
|
||||
DOMException.isInstance(err) &&
|
||||
err.name === "NotFoundError"
|
||||
) {
|
||||
if (err.becauseNoSuchFile) {
|
||||
return Promise.reject({
|
||||
message: `Could not remove download id ${item.id} because the file doesn't exist`,
|
||||
});
|
||||
|
|
@ -1223,7 +1213,7 @@ this.downloads = class extends ExtensionAPIPersistent {
|
|||
let file = FileUtils.File(download.target.path);
|
||||
path = Services.io.newFileURI(file).spec;
|
||||
} else {
|
||||
path = PathUtils.filename(download.target.path);
|
||||
path = OS.Path.basename(download.target.path);
|
||||
pathPrefix = "//";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
|
||||
// eslint-disable-next-line mozilla/reject-importGlobalProperties
|
||||
Cu.importGlobalProperties(["IOUtils", "PathUtils"]);
|
||||
|
||||
const PREF_ASYNC_STACK = "javascript.options.asyncstack";
|
||||
|
||||
const ASYNC_STACKS_ENABLED = Services.prefs.getBoolPref(
|
||||
|
|
@ -131,7 +136,10 @@ this.geckoProfiler = class extends ExtensionAPI {
|
|||
throw new ExtensionError("Path cannot contain a subdirectory.");
|
||||
}
|
||||
|
||||
let dirPath = PathUtils.join(PathUtils.profileDir, "profiler");
|
||||
let dirPath = PathUtils.join(
|
||||
OS.Constants.Path.profileDir,
|
||||
"profiler"
|
||||
);
|
||||
let filePath = PathUtils.join(dirPath, fileName);
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -12,29 +12,26 @@
|
|||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
// Test that the default paths searched for native host manifests
|
||||
// are the ones we expect.
|
||||
add_task(async function test_default_paths() {
|
||||
let expectUser, expectGlobal;
|
||||
switch (AppConstants.platform) {
|
||||
case "macosx": {
|
||||
expectUser = PathUtils.joinRelative(
|
||||
Services.dirsvc.get("Home", Ci.nsIFile).path,
|
||||
"Library/Application Support/Mozilla"
|
||||
);
|
||||
expectUser = OS.Path.join(OS.Constants.Path.homeDir,
|
||||
"Library/Application Support/Mozilla");
|
||||
expectGlobal = "/Library/Application Support/Mozilla";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "linux": {
|
||||
expectUser = PathUtils.join(
|
||||
Services.dirsvc.get("Home", Ci.nsIFile).path,
|
||||
".mozilla"
|
||||
);
|
||||
expectUser = OS.Path.join(OS.Constants.Path.homeDir, ".mozilla");
|
||||
|
||||
const libdir = AppConstants.HAVE_USR_LIB64_DIR ? "lib64" : "lib";
|
||||
expectGlobal = PathUtils.join("/usr", libdir, "mozilla");
|
||||
expectGlobal = OS.Path.join("/usr", libdir, "mozilla");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,12 +46,8 @@ async function background() {
|
|||
"Should fail with a forbidden header"
|
||||
);
|
||||
|
||||
const absoluteFilename = SpecialPowers.Services.appinfo.OS === "WINNT"
|
||||
? "C:\\tmp\\file.gif"
|
||||
: "/tmp/file.gif";
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.downloads.download({url, filename: absoluteFilename}),
|
||||
browser.downloads.download({url, filename: "/tmp/file.gif"}),
|
||||
/filename must not be an absolute path/,
|
||||
"Should fail with an absolute file path"
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
ChromeUtils.defineESModuleGetters(this, {
|
||||
MockRegistry: "resource://testing-common/MockRegistry.sys.mjs",
|
||||
});
|
||||
ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
if (AppConstants.platform == "win") {
|
||||
ChromeUtils.defineESModuleGetters(this, {
|
||||
SubprocessImpl: "resource://gre/modules/subprocess/subprocess_win.sys.mjs",
|
||||
|
|
@ -31,29 +32,28 @@ const TYPE_SLUG =
|
|||
AppConstants.platform === "linux"
|
||||
? "native-messaging-hosts"
|
||||
: "NativeMessagingHosts";
|
||||
OS.File.makeDir(OS.Path.join(tmpDir.path, TYPE_SLUG));
|
||||
|
||||
add_setup(async function setup() {
|
||||
await IOUtils.makeDirectory(PathUtils.join(tmpDir.path, TYPE_SLUG));
|
||||
});
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
await IOUtils.remove(tmpDir.path, { recursive: true });
|
||||
registerCleanupFunction(() => {
|
||||
tmpDir.remove(true);
|
||||
});
|
||||
|
||||
function getPath(filename) {
|
||||
return PathUtils.join(tmpDir.path, TYPE_SLUG, filename);
|
||||
return OS.Path.join(tmpDir.path, TYPE_SLUG, filename);
|
||||
}
|
||||
|
||||
const ID = "native@tests.mozilla.org";
|
||||
|
||||
async function setupHosts(scripts) {
|
||||
const PERMS = { unixMode: 0o755 };
|
||||
|
||||
const pythonPath = await Subprocess.pathSearch(Services.env.get("PYTHON"));
|
||||
|
||||
async function writeManifest(script, scriptPath, path) {
|
||||
let body = `#!${pythonPath} -u\n${script.script}`;
|
||||
|
||||
await IOUtils.writeUTF8(scriptPath, body);
|
||||
await IOUtils.setPermissions(scriptPath, 0o755);
|
||||
await OS.File.writeAtomic(scriptPath, body);
|
||||
await OS.File.setPermissions(scriptPath, PERMS);
|
||||
|
||||
let manifest = {
|
||||
name: script.name,
|
||||
|
|
@ -67,7 +67,7 @@ async function setupHosts(scripts) {
|
|||
script._hookModifyManifest?.(manifest);
|
||||
|
||||
let manifestPath = getPath(`${script.name}.json`);
|
||||
await IOUtils.writeJSON(manifestPath, manifest);
|
||||
await OS.File.writeAtomic(manifestPath, JSON.stringify(manifest));
|
||||
|
||||
return manifestPath;
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ async function setupHosts(scripts) {
|
|||
let scriptPath = getPath(`${script.name}.py`);
|
||||
|
||||
let batBody = `@ECHO OFF\n${pythonPath} -u "${scriptPath}" %*\n`;
|
||||
await IOUtils.writeUTF8(batPath, batBody);
|
||||
await OS.File.writeAtomic(batPath, batBody);
|
||||
|
||||
let manifestPath = await writeManifest(script, scriptPath, batPath);
|
||||
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ add_task(async function test_downloads() {
|
|||
|
||||
// Try to download to an absolute path.
|
||||
const absolutePath = OS.Path.join(
|
||||
WINDOWS ? "C:\\tmp" : "/tmp",
|
||||
WINDOWS ? "\\tmp" : "/tmp",
|
||||
"file_download.txt"
|
||||
);
|
||||
await download({
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ const { Downloads } = ChromeUtils.importESModule(
|
|||
"resource://gre/modules/Downloads.sys.mjs"
|
||||
);
|
||||
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
const { TestUtils } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/TestUtils.sys.mjs"
|
||||
);
|
||||
|
|
@ -230,16 +232,19 @@ let downloadDir;
|
|||
let extension;
|
||||
|
||||
async function waitForCreatedPartFile(baseFilename = "interruptible.html") {
|
||||
const partFilePath = PathUtils.join(downloadDir.path, `${baseFilename}.part`);
|
||||
const partFilePath = `${downloadDir.path}/${baseFilename}.part`;
|
||||
|
||||
info(`Wait for ${partFilePath} to be created`);
|
||||
let lastError;
|
||||
await TestUtils.waitForCondition(
|
||||
() =>
|
||||
IOUtils.exists(partFilePath).catch(err => {
|
||||
lastError = err;
|
||||
return false;
|
||||
}),
|
||||
async () =>
|
||||
OS.File.stat(partFilePath).then(
|
||||
() => true,
|
||||
err => {
|
||||
lastError = err;
|
||||
return false;
|
||||
}
|
||||
),
|
||||
`Wait for the ${partFilePath} to exists before pausing the download`
|
||||
).catch(err => {
|
||||
if (lastError) {
|
||||
|
|
@ -854,8 +859,17 @@ add_task(async function test_file_removeFile_permission_failure() {
|
|||
// completely artificial such as mocking + breaking an internal API.
|
||||
equal(msg.errmsg, "An unexpected error occurred", "Error message redacted");
|
||||
|
||||
// Note: these errors are specific to OS.File.remove. If IOUtils.remove is
|
||||
// used instead in ext-downloads.js (bug 1772932), then the error name is
|
||||
// going to be "NotAllowedError" on Windows and non-Windows.
|
||||
const expectedErrorMessagePattern =
|
||||
AppConstants.platform === "win"
|
||||
? // error 32 = ERROR_SHARING_VIOLATION
|
||||
/Win error 32 during operation remove on file .*subdir.*downloaded_filename/
|
||||
: // error 13 = EACCES
|
||||
/Unix error 13 during operation remove on file .*subdir.*downloaded_filename/;
|
||||
AddonTestUtils.checkMessages(consoleOutput.messages, {
|
||||
expected: [{ message: /NotAllowedError/ }],
|
||||
expected: [{ message: expectedErrorMessagePattern }],
|
||||
});
|
||||
|
||||
ok(await IOUtils.exists(expectedPath), "File exists before removeFile()");
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
let getExtension = () => {
|
||||
return ExtensionTestUtils.loadExtension({
|
||||
background: async function() {
|
||||
|
|
@ -119,7 +121,9 @@ let getExtension = () => {
|
|||
});
|
||||
};
|
||||
|
||||
let verifyProfileData = profile => {
|
||||
let verifyProfileData = bytes => {
|
||||
let textDecoder = new TextDecoder();
|
||||
let profile = JSON.parse(textDecoder.decode(bytes));
|
||||
ok("libs" in profile, "The profile contains libs.");
|
||||
ok("meta" in profile, "The profile contains meta.");
|
||||
ok("threads" in profile, "The profile contains threads.");
|
||||
|
|
@ -148,40 +152,40 @@ add_task(async function testProfilerControl() {
|
|||
extension.sendMessage("test profile");
|
||||
await extension.awaitMessage("tested profile");
|
||||
|
||||
const profilerPath = PathUtils.join(PathUtils.profileDir, "profiler");
|
||||
const profilerPath = OS.Path.join(OS.Constants.Path.profileDir, "profiler");
|
||||
let data, fileName, targetPath;
|
||||
|
||||
// test with file name only
|
||||
fileName = "bar.profile";
|
||||
targetPath = PathUtils.join(profilerPath, fileName);
|
||||
targetPath = OS.Path.join(profilerPath, fileName);
|
||||
extension.sendMessage("test dump to file", { fileName });
|
||||
data = await extension.awaitMessage("tested dump to file");
|
||||
equal(data.error, undefined, "No error thrown");
|
||||
ok(await IOUtils.exists(targetPath), "Saved gecko profile exists.");
|
||||
verifyProfileData(await IOUtils.readJSON(targetPath));
|
||||
ok(await OS.File.exists(targetPath), "Saved gecko profile exists.");
|
||||
verifyProfileData(await OS.File.read(targetPath));
|
||||
|
||||
// test overwriting the formerly created file
|
||||
extension.sendMessage("test dump to file", { fileName });
|
||||
data = await extension.awaitMessage("tested dump to file");
|
||||
equal(data.error, undefined, "No error thrown");
|
||||
ok(await IOUtils.exists(targetPath), "Saved gecko profile exists.");
|
||||
verifyProfileData(await IOUtils.readJSON(targetPath));
|
||||
ok(await OS.File.exists(targetPath), "Saved gecko profile exists.");
|
||||
verifyProfileData(await OS.File.read(targetPath));
|
||||
|
||||
// test with a POSIX path, which is not allowed
|
||||
fileName = "foo/bar.profile";
|
||||
targetPath = PathUtils.join(profilerPath, ...fileName.split("/"));
|
||||
targetPath = OS.Path.join(profilerPath, ...fileName.split("/"));
|
||||
extension.sendMessage("test dump to file", { fileName });
|
||||
data = await extension.awaitMessage("tested dump to file");
|
||||
equal(data.error, "Path cannot contain a subdirectory.");
|
||||
ok(!(await IOUtils.exists(targetPath)), "Gecko profile hasn't been saved.");
|
||||
ok(!(await OS.File.exists(targetPath)), "Gecko profile hasn't been saved.");
|
||||
|
||||
// test with a non POSIX path which is not allowed
|
||||
fileName = "foo\\bar.profile";
|
||||
targetPath = PathUtils.join(profilerPath, ...fileName.split("\\"));
|
||||
targetPath = OS.Path.join(profilerPath, ...fileName.split("\\"));
|
||||
extension.sendMessage("test dump to file", { fileName });
|
||||
data = await extension.awaitMessage("tested dump to file");
|
||||
equal(data.error, "Path cannot contain a subdirectory.");
|
||||
ok(!(await IOUtils.exists(targetPath)), "Gecko profile hasn't been saved.");
|
||||
ok(!(await OS.File.exists(targetPath)), "Gecko profile hasn't been saved.");
|
||||
|
||||
extension.sendMessage("test profile as array buffer");
|
||||
await extension.awaitMessage("tested profile as array buffer");
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
const { FileUtils } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/FileUtils.sys.mjs"
|
||||
);
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
add_setup(async function setup() {
|
||||
add_task(async function setup() {
|
||||
// Add a test .ftl file
|
||||
// (Note: other tests do this by patching L10nRegistry.load() but in
|
||||
// this test L10nRegistry is also loaded in the extension process --
|
||||
|
|
@ -13,8 +14,8 @@ add_setup(async function setup() {
|
|||
let dir = FileUtils.getDir("TmpD", ["l10ntest"]);
|
||||
dir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
|
||||
|
||||
await IOUtils.writeUTF8(
|
||||
PathUtils.join(dir.path, "test.ftl"),
|
||||
await OS.File.writeAtomic(
|
||||
OS.Path.join(dir.path, "test.ftl"),
|
||||
"key = value\n"
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ if (AppConstants.platform == "win") {
|
|||
appname: "relative.echo",
|
||||
expectedError: "An unexpected error occurred",
|
||||
expectedConsoleMessages: [
|
||||
/NativeApp requires absolute path to command on this platform/,
|
||||
/File at path "relative\.echo\.py" does not exist, or is not executable/,
|
||||
],
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ const { TelemetryTestUtils } = ChromeUtils.importESModule(
|
|||
"resource://testing-common/TelemetryTestUtils.sys.mjs"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
});
|
||||
|
||||
const { promiseShutdownManager, promiseStartupManager } = AddonTestUtils;
|
||||
|
||||
const {
|
||||
|
|
@ -58,7 +62,7 @@ async function createExtensionJSONFileWithData(extensionId, data) {
|
|||
await jsonFile._save();
|
||||
const oldStorageFilename = ExtensionStorage.getStorageFile(extensionId);
|
||||
equal(
|
||||
await IOUtils.exists(oldStorageFilename),
|
||||
await OS.File.exists(oldStorageFilename),
|
||||
true,
|
||||
"The old json file has been created"
|
||||
);
|
||||
|
|
@ -315,13 +319,13 @@ add_task(async function test_storage_local_data_migration() {
|
|||
);
|
||||
|
||||
equal(
|
||||
await IOUtils.exists(oldStorageFilename),
|
||||
await OS.File.exists(oldStorageFilename),
|
||||
false,
|
||||
"The old json storage file name should not exist anymore"
|
||||
);
|
||||
|
||||
equal(
|
||||
await IOUtils.exists(`${oldStorageFilename}.migrated`),
|
||||
await OS.File.exists(`${oldStorageFilename}.migrated`),
|
||||
true,
|
||||
"The old json storage file name should have been renamed as .migrated"
|
||||
);
|
||||
|
|
@ -475,14 +479,16 @@ add_task(async function test_storage_local_corrupted_data_migration() {
|
|||
const invalidData = `{"test_key_string": "test_value1"`;
|
||||
const oldStorageFilename = ExtensionStorage.getStorageFile(EXTENSION_ID);
|
||||
|
||||
await IOUtils.makeDirectory(
|
||||
PathUtils.join(PathUtils.profileDir, "browser-extension-data", EXTENSION_ID)
|
||||
const profileDir = OS.Constants.Path.profileDir;
|
||||
await OS.File.makeDir(
|
||||
OS.Path.join(profileDir, "browser-extension-data", EXTENSION_ID),
|
||||
{ from: profileDir, ignoreExisting: true }
|
||||
);
|
||||
|
||||
// Write the json file with some invalid data.
|
||||
await IOUtils.writeUTF8(oldStorageFilename, invalidData, { flush: true });
|
||||
await OS.File.writeAtomic(oldStorageFilename, invalidData, { flush: true });
|
||||
equal(
|
||||
await IOUtils.readUTF8(oldStorageFilename),
|
||||
await OS.File.read(oldStorageFilename, { encoding: "utf-8" }),
|
||||
invalidData,
|
||||
"The old json file has been overwritten with invalid data"
|
||||
);
|
||||
|
|
@ -534,7 +540,7 @@ add_task(async function test_storage_local_corrupted_data_migration() {
|
|||
);
|
||||
|
||||
equal(
|
||||
await IOUtils.exists(`${oldStorageFilename}.corrupt`),
|
||||
await OS.File.exists(`${oldStorageFilename}.corrupt`),
|
||||
true,
|
||||
"The old json storage should still be available if failed to be read"
|
||||
);
|
||||
|
|
@ -623,7 +629,7 @@ add_task(async function test_storage_local_data_migration_failure() {
|
|||
"No data stored in the ExtensionStorageIDB backend as expected"
|
||||
);
|
||||
equal(
|
||||
await IOUtils.exists(oldStorageFilename),
|
||||
await OS.File.exists(oldStorageFilename),
|
||||
true,
|
||||
"The old json storage should still be available if failed to be read"
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ ChromeUtils.defineESModuleGetters(this, {
|
|||
MockRegistry: "resource://testing-common/MockRegistry.sys.mjs",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
});
|
||||
|
||||
const MANIFEST = {
|
||||
name: "test-storage-managed@mozilla.com",
|
||||
description: "",
|
||||
|
|
@ -40,10 +44,10 @@ add_task(async function setup() {
|
|||
|
||||
let typeSlug =
|
||||
AppConstants.platform === "linux" ? "managed-storage" : "ManagedStorage";
|
||||
await IOUtils.makeDirectory(PathUtils.join(tmpDir.path, typeSlug));
|
||||
OS.File.makeDir(OS.Path.join(tmpDir.path, typeSlug));
|
||||
|
||||
let path = PathUtils.join(tmpDir.path, typeSlug, `${MANIFEST.name}.json`);
|
||||
await IOUtils.writeJSON(path, MANIFEST);
|
||||
let path = OS.Path.join(tmpDir.path, typeSlug, `${MANIFEST.name}.json`);
|
||||
await OS.File.writeAtomic(path, JSON.stringify(MANIFEST));
|
||||
|
||||
let registry;
|
||||
if (AppConstants.platform === "win") {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
const HOSTS = new Set(["example.com", "example.org", "example.net"]);
|
||||
|
||||
const server = createHttpServer({ hosts: HOSTS });
|
||||
|
|
@ -68,8 +70,8 @@ server.registerPathHandler("/lorem.html.gz", async (request, response) => {
|
|||
);
|
||||
response.setHeader("Content-Encoding", "gzip", false);
|
||||
|
||||
let data = await IOUtils.read(do_get_file("data/lorem.html.gz").path);
|
||||
response.write(String.fromCharCode(...data));
|
||||
let data = await OS.File.read(do_get_file("data/lorem.html.gz").path);
|
||||
response.write(String.fromCharCode(...new Uint8Array(data)));
|
||||
|
||||
response.finish();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
/* eslint-disable mozilla/no-arbitrary-setTimeout */
|
||||
/* eslint-disable no-shadow */
|
||||
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
const { ExtensionTestCommon } = ChromeUtils.import(
|
||||
"resource://testing-common/ExtensionTestCommon.jsm"
|
||||
);
|
||||
|
|
@ -74,8 +75,8 @@ server.registerPathHandler("/lorem.html.gz", async (request, response) => {
|
|||
);
|
||||
response.setHeader("Content-Encoding", "gzip", false);
|
||||
|
||||
let data = await IOUtils.read(do_get_file("data/lorem.html.gz").path);
|
||||
response.write(String.fromCharCode(...data));
|
||||
let data = await OS.File.read(do_get_file("data/lorem.html.gz").path);
|
||||
response.write(String.fromCharCode(...new Uint8Array(data)));
|
||||
|
||||
response.finish();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ const { Subprocess } = ChromeUtils.importESModule(
|
|||
const { NativeApp } = ChromeUtils.import(
|
||||
"resource://gre/modules/NativeMessaging.jsm"
|
||||
);
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
let registry = null;
|
||||
if (AppConstants.platform == "win") {
|
||||
|
|
@ -55,10 +56,8 @@ let globalDir = dir.clone();
|
|||
globalDir.append("global");
|
||||
globalDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
|
||||
|
||||
add_setup(async function setup() {
|
||||
await IOUtils.makeDirectory(PathUtils.join(userDir.path, TYPE_SLUG));
|
||||
await IOUtils.makeDirectory(PathUtils.join(globalDir.path, TYPE_SLUG));
|
||||
});
|
||||
OS.File.makeDir(OS.Path.join(userDir.path, TYPE_SLUG));
|
||||
OS.File.makeDir(OS.Path.join(globalDir.path, TYPE_SLUG));
|
||||
|
||||
let dirProvider = {
|
||||
getFile(property) {
|
||||
|
|
@ -82,7 +81,7 @@ function writeManifest(path, manifest) {
|
|||
if (typeof manifest != "string") {
|
||||
manifest = JSON.stringify(manifest);
|
||||
}
|
||||
return IOUtils.writeUTF8(path, manifest);
|
||||
return OS.File.writeAtomic(path, manifest);
|
||||
}
|
||||
|
||||
let PYTHON;
|
||||
|
|
@ -157,7 +156,7 @@ add_task(async function test_nonexistent_manifest() {
|
|||
);
|
||||
});
|
||||
|
||||
const USER_TEST_JSON = PathUtils.join(userDir.path, TYPE_SLUG, "test.json");
|
||||
const USER_TEST_JSON = OS.Path.join(userDir.path, TYPE_SLUG, "test.json");
|
||||
|
||||
add_task(async function test_nonexistent_manifest_with_registry_entry() {
|
||||
if (registry) {
|
||||
|
|
@ -169,7 +168,7 @@ add_task(async function test_nonexistent_manifest_with_registry_entry() {
|
|||
);
|
||||
}
|
||||
|
||||
await IOUtils.remove(USER_TEST_JSON);
|
||||
await OS.File.remove(USER_TEST_JSON);
|
||||
let { messages, result } = await promiseConsoleOutput(() =>
|
||||
lookupApplication("test", context)
|
||||
);
|
||||
|
|
@ -284,12 +283,12 @@ add_task(async function test_no_allowed_extensions() {
|
|||
);
|
||||
});
|
||||
|
||||
const GLOBAL_TEST_JSON = PathUtils.join(globalDir.path, TYPE_SLUG, "test.json");
|
||||
const GLOBAL_TEST_JSON = OS.Path.join(globalDir.path, TYPE_SLUG, "test.json");
|
||||
let globalManifest = Object.assign({}, templateManifest);
|
||||
globalManifest.description = "This manifest is from the systemwide directory";
|
||||
|
||||
add_task(async function good_manifest_system_dir() {
|
||||
await IOUtils.remove(USER_TEST_JSON);
|
||||
await OS.File.remove(USER_TEST_JSON);
|
||||
await writeManifest(GLOBAL_TEST_JSON, globalManifest);
|
||||
if (registry) {
|
||||
registry.setValue(
|
||||
|
|
@ -380,8 +379,8 @@ while True:
|
|||
stdout.write(msg)
|
||||
`;
|
||||
|
||||
let scriptPath = PathUtils.join(userDir.path, TYPE_SLUG, "wontdie.py");
|
||||
let manifestPath = PathUtils.join(userDir.path, TYPE_SLUG, "wontdie.json");
|
||||
let scriptPath = OS.Path.join(userDir.path, TYPE_SLUG, "wontdie.py");
|
||||
let manifestPath = OS.Path.join(userDir.path, TYPE_SLUG, "wontdie.json");
|
||||
|
||||
const ID = "native@tests.mozilla.org";
|
||||
let manifest = {
|
||||
|
|
@ -392,12 +391,12 @@ while True:
|
|||
};
|
||||
|
||||
if (AppConstants.platform == "win") {
|
||||
await IOUtils.writeUTF8(scriptPath, SCRIPT);
|
||||
await OS.File.writeAtomic(scriptPath, SCRIPT);
|
||||
|
||||
let batPath = PathUtils.join(userDir.path, TYPE_SLUG, "wontdie.bat");
|
||||
let batPath = OS.Path.join(userDir.path, TYPE_SLUG, "wontdie.bat");
|
||||
let batBody = `@ECHO OFF\n${PYTHON} -u "${scriptPath}" %*\n`;
|
||||
await IOUtils.writeUTF8(batPath, batBody);
|
||||
await IOUtils.setPermissions(batPath, 0o755);
|
||||
await OS.File.writeAtomic(batPath, batBody);
|
||||
await OS.File.setPermissions(batPath, { unixMode: 0o755 });
|
||||
|
||||
manifest.path = batPath;
|
||||
await writeManifest(manifestPath, manifest);
|
||||
|
|
@ -409,8 +408,8 @@ while True:
|
|||
manifestPath
|
||||
);
|
||||
} else {
|
||||
await IOUtils.writeUTF8(scriptPath, `#!${PYTHON} -u\n${SCRIPT}`);
|
||||
await IOUtils.setPermissions(scriptPath, 0o755);
|
||||
await OS.File.writeAtomic(scriptPath, `#!${PYTHON} -u\n${SCRIPT}`);
|
||||
await OS.File.setPermissions(scriptPath, { unixMode: 0o755 });
|
||||
manifest.path = scriptPath;
|
||||
await writeManifest(manifestPath, manifest);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue