--- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm
@@ -29,23 +29,24 @@ XPCOMUtils.defineLazyGetter(this, "Manag
let {Management} = ChromeUtils.import("resource://gre/modules/Extension.jsm", {});
return Management;
});
ChromeUtils.defineModuleGetter(this, "FileTestUtils",
"resource://testing-common/FileTestUtils.jsm");
ChromeUtils.defineModuleGetter(this, "HttpServer",
"resource://testing-common/httpd.js");
+ChromeUtils.defineModuleGetter(this, "InstallRDF",
+ "resource://gre/modules/addons/RDFManifestConverter.jsm");
ChromeUtils.defineModuleGetter(this, "MockRegistrar",
"resource://testing-common/MockRegistrar.jsm");
XPCOMUtils.defineLazyServiceGetters(this, {
aomStartup: ["@mozilla.org/addons/addon-manager-startup;1", "amIAddonManagerStartup"],
proxyService: ["@mozilla.org/network/protocol-proxy-service;1", "nsIProtocolProxyService"],
- rdfService: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"],
uuidGen: ["@mozilla.org/uuid-generator;1", "nsIUUIDGenerator"],
});
XPCOMUtils.defineLazyGetter(this, "AppInfo", () => {
let AppInfo = {};
ChromeUtils.import("resource://testing-common/AppInfo.jsm", AppInfo);
return AppInfo;
});
@@ -56,24 +57,16 @@ const PREF_DISABLE_SECURITY = ("security
const ArrayBufferInputStream = Components.Constructor(
"@mozilla.org/io/arraybuffer-input-stream;1",
"nsIArrayBufferInputStream", "setData");
const nsFile = Components.Constructor(
"@mozilla.org/file/local;1",
"nsIFile", "initWithPath");
-const RDFXMLParser = Components.Constructor(
- "@mozilla.org/rdf/xml-parser;1",
- "nsIRDFXMLParser", "parseString");
-
-const RDFDataSource = Components.Constructor(
- "@mozilla.org/rdf/datasource;1?name=in-memory-datasource",
- "nsIRDFDataSource");
-
const ZipReader = Components.Constructor(
"@mozilla.org/libjar/zip-reader;1",
"nsIZipReader", "open");
const ZipWriter = Components.Constructor(
"@mozilla.org/zipwriter;1",
"nsIZipWriter", "open");
@@ -608,25 +601,18 @@ var AddonTestUtils = {
getIDFromExtension(file) {
return this.getIDFromManifest(this.getManifestURI(file));
},
async getIDFromManifest(manifestURI) {
let body = await fetch(manifestURI.spec);
if (manifestURI.spec.endsWith(".rdf")) {
- let data = await body.text();
-
- let ds = new RDFDataSource();
- new RDFXMLParser(ds, manifestURI, data);
-
- let rdfID = ds.GetTarget(rdfService.GetResource("urn:mozilla:install-manifest"),
- rdfService.GetResource("http://www.mozilla.org/2004/em-rdf#id"),
- true);
- return rdfID.QueryInterface(Ci.nsIRDFLiteral).Value;
+ let manifest = InstallRDF.loadFromBuffer(await body.arrayBuffer()).decode();
+ return manifest.id;
}
let manifest = await body.json();
try {
return manifest.applications.gecko.id;
} catch (e) {
// IDs for WebExtensions are extracted from the certificate when
// not present in the manifest, so just generate a random one.
--- a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm
@@ -27,17 +27,17 @@ ChromeUtils.defineModuleGetter(this, "Ad
"resource://gre/modules/addons/AddonRepository.jsm");
ChromeUtils.defineModuleGetter(this, "Blocklist",
"resource://gre/modules/Blocklist.jsm");
ChromeUtils.defineModuleGetter(this, "CertUtils",
"resource://gre/modules/CertUtils.jsm");
ChromeUtils.defineModuleGetter(this, "ServiceRequest",
"resource://gre/modules/ServiceRequest.jsm");
ChromeUtils.defineModuleGetter(this, "UpdateRDFConverter",
- "resource://gre/modules/addons/UpdateRDFConverter.jsm");
+ "resource://gre/modules/addons/RDFManifestConverter.jsm");
ChromeUtils.import("resource://gre/modules/Log.jsm");
const LOGGER_ID = "addons.update-checker";
// Create a new logger for use by the Addons Update Checker
// (Requires AddonManager.jsm)
var logger = Log.repository.getLogger(LOGGER_ID);
rename from toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm
rename to toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm
--- a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm
+++ b/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm
@@ -1,26 +1,28 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
+ /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-var EXPORTED_SYMBOLS = ["UpdateRDFConverter"];
+var EXPORTED_SYMBOLS = ["InstallRDF", "UpdateRDFConverter"];
ChromeUtils.defineModuleGetter(this, "RDFDataSource",
"resource://gre/modules/addons/RDFDataSource.jsm");
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
const PREFIX_ITEM = "urn:mozilla:item:";
const PREFIX_EXTENSION = "urn:mozilla:extension:";
const PREFIX_THEME = "urn:mozilla:theme:";
const TOOLKIT_ID = "toolkit@mozilla.org";
+const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest";
+
function EM_R(aProperty) {
return `http://www.mozilla.org/2004/em-rdf#${aProperty}`;
}
function getValue(literal) {
return literal && literal.getValue();
}
@@ -45,16 +47,87 @@ class Manifest {
return new this(RDFDataSource.loadFromBuffer(buffer));
}
static async loadFromFile(uri) {
return new this(await RDFDataSource.loadFromFile(uri));
}
}
+class InstallRDF extends Manifest {
+ _readProps(source, obj, props) {
+ for (let prop of props) {
+ let val = getProperty(source, prop);
+ if (val != null) {
+ obj[prop] = val;
+ }
+ }
+ }
+
+ _readArrayProp(source, obj, prop, target, decode = getValue) {
+ let result = Array.from(source.getObjects(EM_R(prop)),
+ target => decode(target));
+ if (result.length) {
+ obj[target] = result;
+ }
+ }
+
+ _readArrayProps(source, obj, props, decode = getValue) {
+ for (let [prop, target] of Object.entries(props)) {
+ this._readArrayProp(source, obj, prop, target, decode);
+ }
+ }
+
+ _readLocaleStrings(source, obj) {
+ this._readProps(source, obj, ["name", "description", "creator", "homepageURL"]);
+ this._readArrayProps(source, obj, {
+ locale: "locales",
+ developer: "developers",
+ translator: "translators",
+ contributor: "contributors",
+ });
+ }
+
+ decode() {
+ let root = this.ds.getResource(RDFURI_INSTALL_MANIFEST_ROOT);
+ let result = {};
+
+ let props = ["id", "version", "type", "updateURL", "optionsURL",
+ "optionsType", "aboutURL", "iconURL", "icon64URL",
+ "bootstrap", "unpack", "strictCompatibility",
+ "hasEmbeddedWebExtension"];
+ this._readProps(root, result, props);
+
+ let decodeTargetApplication = source => {
+ let app = {};
+ this._readProps(source, app, ["id", "minVersion", "maxVersion"]);
+ return app;
+ };
+
+ let decodeLocale = source => {
+ let localized = {};
+ this._readArrayProps(source, localized, ["locale"]);
+ this._readLocaleStrings(source, localized);
+ return localized;
+ };
+
+ this._readLocaleStrings(root, result);
+
+ this._readArrayProps(root, result, {"targetPlatform": "targetPlatforms"});
+ this._readArrayProps(root, result, {"targetApplication": "targetApplications"},
+ decodeTargetApplication);
+ this._readArrayProps(root, result, {"localized": "localized"},
+ decodeLocale);
+ this._readArrayProps(root, result, {"dependency": "dependencies"},
+ source => getProperty(source, "id"));
+
+ return result;
+ }
+}
+
class UpdateRDF extends Manifest {
decode() {
let addons = {};
let result = {addons};
for (let resource of this.ds.getAllResources()) {
let id;
let uri = resource.getURI();
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -40,16 +40,17 @@ XPCOMUtils.defineLazyModuleGetters(this,
FileUtils: "resource://gre/modules/FileUtils.jsm",
NetUtil: "resource://gre/modules/NetUtil.jsm",
OS: "resource://gre/modules/osfile.jsm",
ProductAddonChecker: "resource://gre/modules/addons/ProductAddonChecker.jsm",
UpdateUtils: "resource://gre/modules/UpdateUtils.jsm",
ZipUtils: "resource://gre/modules/ZipUtils.jsm",
AddonInternal: "resource://gre/modules/addons/XPIDatabase.jsm",
+ InstallRDF: "resource://gre/modules/addons/RDFManifestConverter.jsm",
XPIDatabase: "resource://gre/modules/addons/XPIDatabase.jsm",
XPIInternal: "resource://gre/modules/addons/XPIProvider.jsm",
XPIProvider: "resource://gre/modules/addons/XPIProvider.jsm",
});
XPCOMUtils.defineLazyGetter(this, "IconDetails", () => {
return ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm", {}).ExtensionParent.IconDetails;
});
@@ -63,26 +64,21 @@ const BinaryOutputStream = Components.Co
"nsIBinaryOutputStream", "setOutputStream");
const CryptoHash = Components.Constructor("@mozilla.org/security/hash;1",
"nsICryptoHash", "initWithString");
const FileOutputStream = Components.Constructor("@mozilla.org/network/file-output-stream;1",
"nsIFileOutputStream", "init");
const ZipReader = Components.Constructor("@mozilla.org/libjar/zip-reader;1",
"nsIZipReader", "open");
-const RDFDataSource = Components.Constructor(
- "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", "nsIRDFDataSource");
-const parseRDFString = Components.Constructor(
- "@mozilla.org/rdf/xml-parser;1", "nsIRDFXMLParser", "parseString");
-
XPCOMUtils.defineLazyServiceGetters(this, {
gCertDB: ["@mozilla.org/security/x509certdb;1", "nsIX509CertDB"],
- gRDF: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"],
});
+const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
const PREF_ALLOW_NON_RESTARTLESS = "extensions.legacy.non-restartless.enabled";
const PREF_DISTRO_ADDONS_PERMS = "extensions.distroAddons.promptForPermissions";
const PREF_INSTALL_REQUIRESECUREORIGIN = "extensions.install.requireSecureOrigin";
const PREF_PENDING_OPERATIONS = "extensions.pendingOperations";
const PREF_SYSTEM_ADDON_UPDATE_URL = "extensions.systemAddon.update.url";
const PREF_XPI_ENABLED = "xpinstall.enabled";
const PREF_XPI_DIRECT_WHITELISTED = "xpinstall.whitelist.directRequest";
@@ -160,26 +156,22 @@ const FILE_WEB_MANIFEST =
const KEY_PROFILEDIR = "ProfD";
const KEY_TEMPDIR = "TmpD";
const KEY_APP_PROFILE = "app-profile";
const DIR_STAGE = "staged";
const DIR_TRASH = "trash";
-const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest";
-const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
-
// Properties that exist in the install manifest
const PROP_METADATA = ["id", "version", "type", "internalName", "updateURL",
"optionsURL", "optionsType", "aboutURL",
"iconURL", "icon64URL"];
const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];
const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"];
-const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"];
// Map new string type identifiers to old style nsIUpdateItem types.
// Retired values:
// 32 = multipackage xpi file
// 8 = locale
// 256 = apiextension
// 128 = experiment
// theme = 4
@@ -443,54 +435,16 @@ function waitForAllPromises(promises) {
rejectValue = value;
})
);
Promise.all(newPromises)
.then((results) => shouldReject ? reject(rejectValue) : resolve(results));
});
}
-function EM_R(aProperty) {
- return gRDF.GetResource(PREFIX_NS_EM + aProperty);
-}
-
-/**
- * Converts an RDF literal, resource or integer into a string.
- *
- * @param {nsISupports} aLiteral
- * The RDF object to convert
- * @returns {string?}
- * A string if the object could be converted or null
- */
-function getRDFValue(aLiteral) {
- if (aLiteral instanceof Ci.nsIRDFLiteral)
- return aLiteral.Value;
- if (aLiteral instanceof Ci.nsIRDFResource)
- return aLiteral.Value;
- if (aLiteral instanceof Ci.nsIRDFInt)
- return aLiteral.Value;
- return null;
-}
-
-/**
- * Gets an RDF property as a string
- *
- * @param {nsIRDFDataSource} aDs
- * The RDF datasource to read the property from
- * @param {nsIRDFResource} aResource
- * The RDF resource to read the property from
- * @param {string} aProperty
- * The property to read
- * @returns {string?}
- * A string if the property existed or null
- */
-function getRDFProperty(aDs, aResource, aProperty) {
- return getRDFValue(aDs.GetTarget(aResource, EM_R(aProperty), true));
-}
-
/**
* Reads an AddonInternal object from a manifest stream.
*
* @param {nsIURI} aUri
* A |file:| or |jar:| URL for the manifest
* @returns {AddonInternal}
* @throws if the install manifest in the stream is corrupt or could not
* be read
@@ -623,50 +577,37 @@ async function loadManifestFromWebManife
* The URI that the manifest is being read from
* @param {string} aData
* The manifest text
* @returns {AddonInternal}
* @throws if the install manifest in the RDF stream is corrupt or could not
* be read
*/
async function loadManifestFromRDF(aUri, aData) {
- function getPropertyArray(aDs, aSource, aProperty) {
- let values = [];
- let targets = aDs.GetTargets(aSource, EM_R(aProperty), true);
- while (targets.hasMoreElements())
- values.push(getRDFValue(targets.getNext()));
-
- return values;
- }
-
/**
* Reads locale properties from either the main install manifest root or
* an em:localized section in the install manifest.
*
- * @param {nsIRDFDataSource} aDs
- * The datasource to read from.
- * @param {nsIRDFResource} aSource
- * The resource to read the properties from.
+ * @param {Object} aSource
+ * The resource to read the properties from.
* @param {boolean} isDefault
* True if the locale is to be read from the main install manifest
* root
* @param {string[]} aSeenLocales
* An array of locale names already seen for this install manifest.
* Any locale names seen as a part of this function will be added to
* this array
* @returns {Object}
* an object containing the locale properties
*/
- function readLocale(aDs, aSource, isDefault, aSeenLocales) {
- let locale = { };
+ function readLocale(aSource, isDefault, aSeenLocales) {
+ let locale = {};
if (!isDefault) {
locale.locales = [];
- let targets = ds.GetTargets(aSource, EM_R("locale"), true);
- while (targets.hasMoreElements()) {
- let localeName = getRDFValue(targets.getNext());
+ for (let localeName of aSource.locales || []) {
if (!localeName) {
logger.warn("Ignoring empty locale in localized properties");
continue;
}
if (aSeenLocales.includes(localeName)) {
logger.warn("Ignoring duplicate locale in localized properties");
continue;
}
@@ -675,42 +616,36 @@ async function loadManifestFromRDF(aUri,
}
if (locale.locales.length == 0) {
logger.warn("Ignoring localized properties with no listed locales");
return null;
}
}
- for (let prop of PROP_LOCALE_SINGLE) {
- locale[prop] = getRDFProperty(aDs, aSource, prop);
- }
-
- for (let prop of PROP_LOCALE_MULTI) {
- // Don't store empty arrays
- let props = getPropertyArray(aDs, aSource,
- prop.substring(0, prop.length - 1));
- if (props.length > 0)
- locale[prop] = props;
+ for (let prop of [...PROP_LOCALE_SINGLE, ...PROP_LOCALE_MULTI]) {
+ if (hasOwnProperty(aSource, prop)) {
+ locale[prop] = aSource[prop];
+ }
}
return locale;
}
- let ds = new RDFDataSource();
- parseRDFString(ds, aUri, aData);
-
- let root = gRDF.GetResource(RDFURI_INSTALL_MANIFEST_ROOT);
+ let manifest = InstallRDF.loadFromString(aData).decode();
+
let addon = new AddonInternal();
for (let prop of PROP_METADATA) {
- addon[prop] = getRDFProperty(ds, root, prop);
+ if (hasOwnProperty(manifest, prop)) {
+ addon[prop] = manifest[prop];
+ }
}
if (!addon.type) {
- addon.type = addon.internalName ? "theme" : "extension";
+ addon.type = "extension";
} else {
let type = addon.type;
addon.type = null;
for (let name in TYPES) {
if (TYPES[name] == type) {
addon.type = name;
break;
}
@@ -722,26 +657,26 @@ async function loadManifestFromRDF(aUri,
if (!addon.id)
throw new Error("No ID in install manifest");
if (!gIDTest.test(addon.id))
throw new Error("Illegal add-on ID " + addon.id);
if (!addon.version)
throw new Error("No version in install manifest");
- addon.strictCompatibility = !(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) ||
- getRDFProperty(ds, root, "strictCompatibility") == "true";
+ addon.strictCompatibility = (!(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) ||
+ manifest.strictCompatibility == "true");
// Only read these properties for extensions.
if (addon.type == "extension") {
- addon.bootstrap = getRDFProperty(ds, root, "bootstrap") == "true";
+ addon.bootstrap = manifest.bootstrap == "true";
if (!addon.bootstrap && !Services.prefs.getBoolPref(PREF_ALLOW_NON_RESTARTLESS, false))
throw new Error(`Non-restartless extensions no longer supported`);
- addon.hasEmbeddedWebExtension = getRDFProperty(ds, root, "hasEmbeddedWebExtension") == "true";
+ addon.hasEmbeddedWebExtension = manifest.hasEmbeddedWebExtension == "true";
if (addon.optionsType &&
addon.optionsType != AddonManager.OPTIONS_INLINE_BROWSER &&
addon.optionsType != AddonManager.OPTIONS_TYPE_TAB) {
throw new Error("Install manifest specifies unknown optionsType: " + addon.optionsType);
}
if (addon.hasEmbeddedWebExtension) {
@@ -763,73 +698,52 @@ async function loadManifestFromRDF(aUri,
}
// Only extensions are allowed to provide an optionsURL, optionsType,
// optionsBrowserStyle, or aboutURL. For all other types they are silently ignored
addon.aboutURL = null;
addon.optionsBrowserStyle = null;
addon.optionsType = null;
addon.optionsURL = null;
-
- if (addon.type == "theme") {
- if (!addon.internalName)
- throw new Error("Themes must include an internalName property");
- addon.skinnable = getRDFProperty(ds, root, "skinnable") == "true";
- }
}
- addon.defaultLocale = readLocale(ds, root, true);
+ addon.defaultLocale = readLocale(manifest, true);
let seenLocales = [];
addon.locales = [];
- let targets = ds.GetTargets(root, EM_R("localized"), true);
- while (targets.hasMoreElements()) {
- let target = targets.getNext().QueryInterface(Ci.nsIRDFResource);
- let locale = readLocale(ds, target, false, seenLocales);
+ for (let localeData of manifest.localized || []) {
+ let locale = readLocale(localeData, false, seenLocales);
if (locale)
addon.locales.push(locale);
}
- let dependencies = new Set();
- targets = ds.GetTargets(root, EM_R("dependency"), true);
- while (targets.hasMoreElements()) {
- let target = targets.getNext().QueryInterface(Ci.nsIRDFResource);
- let id = getRDFProperty(ds, target, "id");
- dependencies.add(id);
- }
+ let dependencies = new Set(manifest.dependencies);
addon.dependencies = Object.freeze(Array.from(dependencies));
let seenApplications = [];
addon.targetApplications = [];
- targets = ds.GetTargets(root, EM_R("targetApplication"), true);
- while (targets.hasMoreElements()) {
- let target = targets.getNext().QueryInterface(Ci.nsIRDFResource);
- let targetAppInfo = {};
- for (let prop of PROP_TARGETAPP) {
- targetAppInfo[prop] = getRDFProperty(ds, target, prop);
- }
- if (!targetAppInfo.id || !targetAppInfo.minVersion ||
- !targetAppInfo.maxVersion) {
+ for (let targetApp of manifest.targetApplications || []) {
+ if (!targetApp.id || !targetApp.minVersion ||
+ !targetApp.maxVersion) {
logger.warn("Ignoring invalid targetApplication entry in install manifest");
continue;
}
- if (seenApplications.includes(targetAppInfo.id)) {
- logger.warn("Ignoring duplicate targetApplication entry for " + targetAppInfo.id +
+ if (seenApplications.includes(targetApp.id)) {
+ logger.warn("Ignoring duplicate targetApplication entry for " + targetApp.id +
" in install manifest");
continue;
}
- seenApplications.push(targetAppInfo.id);
- addon.targetApplications.push(targetAppInfo);
+ seenApplications.push(targetApp.id);
+ addon.targetApplications.push(targetApp);
}
// Note that we don't need to check for duplicate targetPlatform entries since
// the RDF service coalesces them for us.
- let targetPlatforms = getPropertyArray(ds, root, "targetPlatform");
addon.targetPlatforms = [];
- for (let targetPlatform of targetPlatforms) {
+ for (let targetPlatform of manifest.targetPlatforms || []) {
let platform = {
os: null,
abi: null
};
let pos = targetPlatform.indexOf("_");
if (pos != -1) {
platform.os = targetPlatform.substring(0, pos);
--- a/toolkit/mozapps/extensions/internal/moz.build
+++ b/toolkit/mozapps/extensions/internal/moz.build
@@ -8,18 +8,18 @@ EXTRA_JS_MODULES.addons += [
'AddonRepository.jsm',
'AddonSettings.jsm',
'AddonUpdateChecker.jsm',
'Content.js',
'GMPProvider.jsm',
'LightweightThemeImageOptimizer.jsm',
'ProductAddonChecker.jsm',
'RDFDataSource.jsm',
+ 'RDFManifestConverter.jsm',
'SpellCheckDictionaryBootstrap.js',
- 'UpdateRDFConverter.jsm',
'XPIDatabase.jsm',
'XPIInstall.jsm',
'XPIProvider.jsm',
]
TESTING_JS_MODULES += [
'AddonTestUtils.jsm',
]
--- a/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf
+++ b/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf
@@ -20,8 +20,9 @@
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
+</RDF>
--- a/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf
+++ b/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf
@@ -20,8 +20,9 @@
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
+</RDF>
--- a/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js
@@ -1,14 +1,15 @@
"use strict";
// Tests the update RDF to JSON converter.
ChromeUtils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm");
-ChromeUtils.import("resource://gre/modules/addons/UpdateRDFConverter.jsm");
+ChromeUtils.defineModuleGetter(this, "UpdateRDFConverter",
+ "resource://gre/modules/addons/RDFManifestConverter.jsm");
var testserver = AddonTestUtils.createHttpServer({hosts: ["example.com"]});
testserver.registerDirectory("/data/", do_get_file("data"));
const BASE_URL = "http://example.com/data";
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");