diff options
Diffstat (limited to 'uriloader/exthandler/tests/unit/test_getTypeFromExtension_with_empty_Content_Type.js')
-rw-r--r-- | uriloader/exthandler/tests/unit/test_getTypeFromExtension_with_empty_Content_Type.js | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/uriloader/exthandler/tests/unit/test_getTypeFromExtension_with_empty_Content_Type.js b/uriloader/exthandler/tests/unit/test_getTypeFromExtension_with_empty_Content_Type.js new file mode 100644 index 000000000..1ae2a6fcf --- /dev/null +++ b/uriloader/exthandler/tests/unit/test_getTypeFromExtension_with_empty_Content_Type.js @@ -0,0 +1,186 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * 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/. */ + +/** + * Test for bug 484579 <https://bugzilla.mozilla.org/show_bug.cgi?id=484579>: + * nsIMIMEService.getTypeFromExtension may fail unexpectedly on Windows when + * "Content Type" is empty in the registry. + */ +function run_test() { + // --- Preliminary platform check --- + + // If this test is not running on the Windows platform, stop now, before + // calling XPCOMUtils.generateQI during the MockWindowsRegKey declaration. + if (mozinfo.os != "win") + return; + + // --- Modified nsIWindowsRegKey implementation --- + + Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + + /** + * Constructs a new mock registry key by wrapping the provided object. + * + * This mock implementation is tailored for this test, and forces consumers + * of the readStringValue method to believe that the "Content Type" value of + * the ".txt" key under HKEY_CLASSES_ROOT is an empty string. + * + * The same value read from "HKEY_LOCAL_MACHINE\SOFTWARE\Classes" is not + * affected. + * + * @param aWrappedObject An actual nsIWindowsRegKey implementation. + */ + function MockWindowsRegKey(aWrappedObject) { + this._wrappedObject = aWrappedObject; + + // This function creates a forwarding function for wrappedObject + function makeForwardingFunction(functionName) { + return function() { + return aWrappedObject[functionName].apply(aWrappedObject, arguments); + } + } + + // Forward all the functions that are not explicitly overridden + for (var propertyName in aWrappedObject) { + if (!(propertyName in this)) { + if (typeof aWrappedObject[propertyName] == "function") { + this[propertyName] = makeForwardingFunction(propertyName); + } else { + this[propertyName] = aWrappedObject[propertyName]; + } + } + } + } + + MockWindowsRegKey.prototype = { + // --- Overridden nsISupports interface functions --- + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowsRegKey]), + + // --- Overridden nsIWindowsRegKey interface functions --- + + open: function(aRootKey, aRelPath, aMode) { + // Remember the provided root key and path + this._rootKey = aRootKey; + this._relPath = aRelPath; + + // Create the actual registry key + return this._wrappedObject.open(aRootKey, aRelPath, aMode); + }, + + openChild: function(aRelPath, aMode) { + // Open the child key and wrap it + var innerKey = this._wrappedObject.openChild(aRelPath, aMode); + var key = new MockWindowsRegKey(innerKey); + + // Set the properties of the child key and return it + key._rootKey = this._rootKey; + key._relPath = this._relPath + aRelPath; + return key; + }, + + createChild: function(aRelPath, aMode) { + // Create the child key and wrap it + var innerKey = this._wrappedObject.createChild(aRelPath, aMode); + var key = new MockWindowsRegKey(innerKey); + + // Set the properties of the child key and return it + key._rootKey = this._rootKey; + key._relPath = this._relPath + aRelPath; + return key; + }, + + get childCount() { + return this._wrappedObject.childCount; + }, + + get valueCount() { + return this._wrappedObject.valueCount; + }, + + readStringValue: function(aName) { + // If this is the key under test, return a fake value + if (this._rootKey == Ci.nsIWindowsRegKey.ROOT_KEY_CLASSES_ROOT && + this._relPath.toLowerCase() == ".txt" && + aName.toLowerCase() == "content type") { + return ""; + } + + // Return the real value in the registry + return this._wrappedObject.readStringValue(aName); + } + }; + + // --- Mock nsIWindowsRegKey factory --- + + var componentRegistrar = Components.manager. + QueryInterface(Ci.nsIComponentRegistrar); + + var originalWindowsRegKeyCID; + var mockWindowsRegKeyFactory; + + const kMockCID = Components.ID("{9b23dfe9-296b-4740-ba1c-d39c9a16e55e}"); + const kWindowsRegKeyContractID = "@mozilla.org/windows-registry-key;1"; + const kWindowsRegKeyClassName = "nsWindowsRegKey"; + + function registerMockWindowsRegKeyFactory() { + mockWindowsRegKeyFactory = { + createInstance: function(aOuter, aIid) { + if (aOuter != null) + throw Cr.NS_ERROR_NO_AGGREGATION; + + var innerKey = originalWindowsRegKeyFactory.createInstance(null, aIid); + var key = new MockWindowsRegKey(innerKey); + + return key.QueryInterface(aIid); + } + }; + + // Preserve the original factory + originalWindowsRegKeyCID = Cc[kWindowsRegKeyContractID].number; + + // Register the mock factory + componentRegistrar.registerFactory( + kMockCID, + "Mock Windows Registry Key Implementation", + kWindowsRegKeyContractID, + mockWindowsRegKeyFactory + ); + } + + function unregisterMockWindowsRegKeyFactory() { + // Free references to the mock factory + componentRegistrar.unregisterFactory( + kMockCID, + mockWindowsRegKeyFactory + ); + + // Restore the original factory + componentRegistrar.registerFactory( + Components.ID(originalWindowsRegKeyCID), + "", + kWindowsRegKeyContractID, + null + ); + } + + // --- Test procedure --- + + // Activate the override of the ".txt" file association data in the registry + registerMockWindowsRegKeyFactory(); + try { + // Try and get the MIME type associated with the extension. If this + // operation does not throw an unexpected exception, the test succeeds. + var type = Cc["@mozilla.org/mime;1"]. + getService(Ci.nsIMIMEService). + getTypeFromExtension(".txt"); + } catch (e if (e instanceof Ci.nsIException && + e.result == Cr.NS_ERROR_NOT_AVAILABLE)) { + // This is an expected exception, thrown if the type can't be determined + } finally { + // Ensure we restore the original factory when the test is finished + unregisterMockWindowsRegKeyFactory(); + } +} |