diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index f060c457cee2..566e6435ea05 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -118,9 +118,6 @@ #ifdef MOZ_WASM_SANDBOXING_OGG @BINPATH@/@DLL_PREFIX@oggwasm@DLL_SUFFIX@ #endif -#ifdef MOZ_WASM_SANDBOXING_HUNSPELL -@BINPATH@/@DLL_PREFIX@hunspellwasm@DLL_SUFFIX@ -#endif ; We don't have a complete view of which dlls to expect when doing an artifact ; build because we haven't run the relevant parts of configure, so we guess diff --git a/extensions/spellcheck/hunspell/glue/RLBoxHunspell.cpp b/extensions/spellcheck/hunspell/glue/RLBoxHunspell.cpp deleted file mode 100644 index 9b30edd7c6f6..000000000000 --- a/extensions/spellcheck/hunspell/glue/RLBoxHunspell.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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/. */ - -#include "mozilla/Assertions.h" -#ifdef MOZ_WASM_SANDBOXING_HUNSPELL -# include "mozilla/ipc/LibrarySandboxPreload.h" -#endif -#include "RLBoxHunspell.h" -#include "mozHunspellRLBoxGlue.h" -#include "mozHunspellRLBoxHost.h" - -using namespace rlbox; -using namespace mozilla; - -// Helper function for allocating and copying nsAutoCString into sandbox -static tainted_hunspell allocStrInSandbox( - rlbox_sandbox_hunspell& aSandbox, const nsAutoCString& str) { - size_t size = str.Length() + 1; - tainted_hunspell t_str = aSandbox.malloc_in_sandbox(size); - MOZ_RELEASE_ASSERT(t_str); - rlbox::memcpy(aSandbox, t_str, str.get(), size); - return t_str; -} - -// Helper function for allocating and copying std::string into sandbox -static tainted_hunspell allocStrInSandbox( - rlbox_sandbox_hunspell& aSandbox, const std::string& str) { - size_t size = str.size() + 1; - tainted_hunspell t_str = aSandbox.malloc_in_sandbox(size); - MOZ_RELEASE_ASSERT(t_str); - rlbox::memcpy(aSandbox, t_str, str.c_str(), size); - return t_str; -} - -RLBoxHunspell::RLBoxHunspell(const nsAutoCString& affpath, - const nsAutoCString& dpath) - : mHandle(nullptr) { -#ifdef MOZ_WASM_SANDBOXING_HUNSPELL - // Firefox preloads the library externally to ensure we won't be stopped by - // the content sandbox - const bool external_loads_exist = true; - // See Bug 1606981: In some environments allowing stdio in the wasm sandbox - // fails as the I/O redirection involves querying meta-data of file - // descriptors. This querying fails in some environments. - const bool allow_stdio = false; - mSandbox.create_sandbox(mozilla::ipc::GetSandboxedHunspellPath().get(), - external_loads_exist, allow_stdio); -#else - mSandbox.create_sandbox(); -#endif - - // Add the aff and dict files to allow list - mozHunspellCallbacks::AllowFile(affpath); - mozHunspellCallbacks::AllowFile(dpath); - - // Register callbacks - mCreateFilemgr = - mSandbox.register_callback(mozHunspellCallbacks::CreateFilemgr); - mGetLine = mSandbox.register_callback(mozHunspellCallbacks::GetLine); - mGetLineNum = mSandbox.register_callback(mozHunspellCallbacks::GetLineNum); - mDestructFilemgr = - mSandbox.register_callback(mozHunspellCallbacks::DestructFilemgr); - mHunspellToUpperCase = - mSandbox.register_callback(mozHunspellCallbacks::ToUpperCase); - mHunspellToLowerCase = - mSandbox.register_callback(mozHunspellCallbacks::ToLowerCase); - mHunspellGetCurrentCS = - mSandbox.register_callback(mozHunspellCallbacks::GetCurrentCS); - - mSandbox.invoke_sandbox_function(RegisterHunspellCallbacks, mCreateFilemgr, - mGetLine, mGetLineNum, mDestructFilemgr, - mHunspellToUpperCase, mHunspellToLowerCase, - mHunspellGetCurrentCS); - - // Copy the affpath and dpath into the sandbox - tainted_hunspell t_affpath = allocStrInSandbox(mSandbox, affpath); - tainted_hunspell t_dpath = allocStrInSandbox(mSandbox, dpath); - - // Create handle - mHandle = mSandbox.invoke_sandbox_function( - Hunspell_create, rlbox::sandbox_const_cast(t_affpath), - rlbox::sandbox_const_cast(t_dpath)); - MOZ_RELEASE_ASSERT(mHandle); - - mSandbox.free_in_sandbox(t_dpath); - mSandbox.free_in_sandbox(t_affpath); - - // Get dictionary encoding - tainted_hunspell t_enc = - mSandbox.invoke_sandbox_function(Hunspell_get_dic_encoding, mHandle); - t_enc.copy_and_verify_string([&](std::unique_ptr enc) { - size_t len = std::strlen(enc.get()); - mDicEncoding = std::string(enc.get(), len); - }); -} - -RLBoxHunspell::~RLBoxHunspell() { - // Call hunspell's destroy which frees mHandle - mSandbox.invoke_sandbox_function(Hunspell_destroy, mHandle); - mHandle = nullptr; - - // Unregister callbacks - mDestructFilemgr.unregister(); - mGetLineNum.unregister(); - mGetLine.unregister(); - mCreateFilemgr.unregister(); - mHunspellToUpperCase.unregister(); - mHunspellToLowerCase.unregister(); - mHunspellGetCurrentCS.unregister(); - - // Clear any callback data and allow list - mozHunspellCallbacks::Clear(); - - // Dstroy sandbox - mSandbox.destroy_sandbox(); -} - -int RLBoxHunspell::spell(const std::string& stdWord) { - // Copy word into the sandbox - tainted_hunspell t_word = allocStrInSandbox(mSandbox, stdWord); - - // Check word - int good = mSandbox - .invoke_sandbox_function( - Hunspell_spell, mHandle, - rlbox::sandbox_const_cast(t_word)) - .copy_and_verify([](int good) { return good; }); - mSandbox.free_in_sandbox(t_word); - return good; -} - -const std::string& RLBoxHunspell::get_dict_encoding() const { - return mDicEncoding; -} - -std::vector RLBoxHunspell::suggest(const std::string& stdWord) { - // Copy word into the sandbox - tainted_hunspell t_word = allocStrInSandbox(mSandbox, stdWord); - - // Allocate suggestion list in the sandbox - tainted_hunspell t_slst = mSandbox.malloc_in_sandbox(); - *t_slst = nullptr; - - // Get suggestions - int nr = mSandbox - .invoke_sandbox_function( - Hunspell_suggest, mHandle, t_slst, - rlbox::sandbox_const_cast(t_word)) - .copy_and_verify([](int nr) { - MOZ_RELEASE_ASSERT(nr >= 0); - return nr; - }); - - // Copy suggestions from sandbox - std::vector suggestions; - suggestions.reserve(nr); - for (int i = 0; i < nr; i++) { - tainted_hunspell t_sug = (*t_slst)[i]; - MOZ_RELEASE_ASSERT(t_sug); - t_sug.copy_and_verify_string([&](std::unique_ptr sug) { - size_t len = std::strlen(sug.get()); - suggestions.push_back(std::string(sug.get(), len)); - }); - } - - mSandbox.free_in_sandbox(t_word); - mSandbox.free_in_sandbox(t_slst); - return suggestions; -} diff --git a/extensions/spellcheck/hunspell/glue/RLBoxHunspell.h b/extensions/spellcheck/hunspell/glue/RLBoxHunspell.h deleted file mode 100644 index 9572280bc57d..000000000000 --- a/extensions/spellcheck/hunspell/glue/RLBoxHunspell.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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/. */ - -#ifndef EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_RLBOXHUNSPELL_H_ -#define EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_RLBOXHUNSPELL_H_ - -#include "RLBoxHunspellTypes.h" - -// Load general firefox configuration of RLBox -#include "mozilla/rlbox/rlbox_config.h" - -#ifdef MOZ_WASM_SANDBOXING_HUNSPELL -# include "mozilla/rlbox/rlbox_lucet_sandbox.hpp" -#else -// Extra configuration for no-op sandbox -# define RLBOX_USE_STATIC_CALLS() rlbox_noop_sandbox_lookup_symbol -# include "mozilla/rlbox/rlbox_noop_sandbox.hpp" -#endif - -#include "mozilla/rlbox/rlbox.hpp" - -#include -#include "mozHunspellRLBoxGlue.h" - -class RLBoxHunspell { - public: - RLBoxHunspell(const nsAutoCString& affpath, const nsAutoCString& dpath); - ~RLBoxHunspell(); - - int spell(const std::string& stdWord); - const std::string& get_dict_encoding() const; - - std::vector suggest(const std::string& word); - - private: - rlbox_sandbox_hunspell mSandbox; - sandbox_callback_hunspell mCreateFilemgr; - sandbox_callback_hunspell mGetLine; - sandbox_callback_hunspell mGetLineNum; - sandbox_callback_hunspell mDestructFilemgr; - sandbox_callback_hunspell mHunspellToUpperCase; - sandbox_callback_hunspell mHunspellToLowerCase; - sandbox_callback_hunspell mHunspellGetCurrentCS; - tainted_hunspell mHandle; - std::string mDicEncoding; -}; - -#endif diff --git a/extensions/spellcheck/hunspell/glue/RLBoxHunspellTypes.h b/extensions/spellcheck/hunspell/glue/RLBoxHunspellTypes.h deleted file mode 100644 index 8d98cf8ba5b1..000000000000 --- a/extensions/spellcheck/hunspell/glue/RLBoxHunspellTypes.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 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/. */ - -#ifndef EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_RLBOXHUNSPELLTYPES_H_ -#define EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_RLBOXHUNSPELLTYPES_H_ - -#include -#include "mozilla/rlbox/rlbox_types.hpp" -#include "hunspell_csutil.hxx" - -#ifdef MOZ_WASM_SANDBOXING_HUNSPELL -namespace rlbox { -class rlbox_lucet_sandbox; -} -using rlbox_hunspell_sandbox_type = rlbox::rlbox_lucet_sandbox; -#else -using rlbox_hunspell_sandbox_type = rlbox::rlbox_noop_sandbox; -#endif - -using rlbox_sandbox_hunspell = - rlbox::rlbox_sandbox; -template -using sandbox_callback_hunspell = - rlbox::sandbox_callback; -template -using tainted_hunspell = rlbox::tainted; -template -using tainted_opaque_hunspell = - rlbox::tainted_opaque; -template -using tainted_volatile_hunspell = - rlbox::tainted_volatile; -using rlbox::tainted_boolean_hint; - -#define sandbox_fields_reflection_hunspell_class_cs_info(f, g, ...) \ - f(unsigned char, ccase, FIELD_NORMAL, ##__VA_ARGS__) g() \ - f(unsigned char, clower, FIELD_NORMAL, ##__VA_ARGS__) g() \ - f(unsigned char, cupper, FIELD_NORMAL, ##__VA_ARGS__) g() - -#define sandbox_fields_reflection_hunspell_allClasses(f, ...) \ - f(cs_info, hunspell, ##__VA_ARGS__) - -#endif diff --git a/extensions/spellcheck/hunspell/glue/hunspell_csutil.cxx b/extensions/spellcheck/hunspell/glue/hunspell_csutil.cxx deleted file mode 100644 index c432ae98fbae..000000000000 --- a/extensions/spellcheck/hunspell/glue/hunspell_csutil.cxx +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * Copyright (C) 2002-2017 Németh László - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. - * - * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, - * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, - * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, - * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, - * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada - * And Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. All modifications to the source code must be clearly marked as - * such. Binary redistributions based on modified source code - * must be clearly marked as modified versions in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include "hunspell_csutil.hxx" -#include "mozilla/Encoding.h" - -/* This is a copy of get_current_cs from the hunspell csutil.cxx file. - */ -struct cs_info* hunspell_get_current_cs(const std::string& es) { - struct cs_info* ccs = new cs_info[256]; - // Initialze the array with dummy data so that we wouldn't need - // to return null in case of failures. - for (int i = 0; i <= 0xff; ++i) { - ccs[i].ccase = false; - ccs[i].clower = i; - ccs[i].cupper = i; - } - - auto encoding = Encoding::ForLabelNoReplacement(es); - if (!encoding) { - return ccs; - } - auto encoder = encoding->NewEncoder(); - auto decoder = encoding->NewDecoderWithoutBOMHandling(); - - for (unsigned int i = 0; i <= 0xff; ++i) { - bool success = false; - // We want to find the upper/lowercase equivalents of each byte - // in this 1-byte character encoding. Call our encoding/decoding - // APIs separately for each byte since they may reject some of the - // bytes, and we want to handle errors separately for each byte. - uint8_t lower, upper; - do { - if (i == 0) break; - uint8_t source = uint8_t(i); - char16_t uni[2]; - char16_t uniCased; - uint8_t destination[4]; - auto src1 = Span(&source, 1); - auto dst1 = Span(uni); - auto src2 = Span(&uniCased, 1); - auto dst2 = Span(destination); - - uint32_t result; - size_t read; - size_t written; - Tie(result, read, written) = - decoder->DecodeToUTF16WithoutReplacement(src1, dst1, true); - if (result != kInputEmpty || read != 1 || written != 1) { - break; - } - - uniCased = ToLowerCase(uni[0]); - Tie(result, read, written) = - encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true); - if (result != kInputEmpty || read != 1 || written != 1) { - break; - } - lower = destination[0]; - - uniCased = ToUpperCase(uni[0]); - Tie(result, read, written) = - encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true); - if (result != kInputEmpty || read != 1 || written != 1) { - break; - } - upper = destination[0]; - - success = true; - } while (0); - - encoding->NewEncoderInto(*encoder); - encoding->NewDecoderWithoutBOMHandlingInto(*decoder); - - if (success) { - ccs[i].cupper = upper; - ccs[i].clower = lower; - } else { - ccs[i].cupper = i; - ccs[i].clower = i; - } - - if (ccs[i].clower != (unsigned char)i) - ccs[i].ccase = true; - else - ccs[i].ccase = false; - } - - return ccs; -} diff --git a/extensions/spellcheck/hunspell/glue/hunspell_csutil.hxx b/extensions/spellcheck/hunspell/glue/hunspell_csutil.hxx deleted file mode 100644 index 00dd89a96475..000000000000 --- a/extensions/spellcheck/hunspell/glue/hunspell_csutil.hxx +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * Copyright (C) 2002-2017 Németh László - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. - * - * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, - * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, - * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, - * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, - * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada - * And Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. All modifications to the source code must be clearly marked as - * such. Binary redistributions based on modified source code - * must be clearly marked as modified versions in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#ifndef EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_HUNSPELL_CSUTIL_H_ -#define EXTENSIONS_SPELLCHECK_HUNSPELL_GLUE_HUNSPELL_CSUTIL_H_ - -/* We need get_current_cs from hunspell's csutil to live outside the RLBox - * sandbox (since it relies on a Gecko encoding bits) and then expose it to the - * sandboxed hunspell. - */ - -struct cs_info { - unsigned char ccase; - unsigned char clower; - unsigned char cupper; -}; - -struct cs_info* hunspell_get_current_cs(const std::string& es); - -#endif diff --git a/extensions/spellcheck/hunspell/glue/moz.build b/extensions/spellcheck/hunspell/glue/moz.build index 4e1ec065c248..7d5a110d7d83 100644 --- a/extensions/spellcheck/hunspell/glue/moz.build +++ b/extensions/spellcheck/hunspell/glue/moz.build @@ -5,12 +5,10 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. UNIFIED_SOURCES += [ - "hunspell_csutil.cxx", "mozHunspell.cpp", - "mozHunspellRLBoxHost.cpp", + "mozHunspellFileMgrHost.cpp", "RemoteSpellCheckEngineChild.cpp", "RemoteSpellCheckEngineParent.cpp", - "RLBoxHunspell.cpp", ] DEFINES["HUNSPELL_STATIC"] = True diff --git a/extensions/spellcheck/hunspell/glue/mozHunspell.cpp b/extensions/spellcheck/hunspell/glue/mozHunspell.cpp index 8fd5e6f1f1ec..f722d9ac21c6 100644 --- a/extensions/spellcheck/hunspell/glue/mozHunspell.cpp +++ b/extensions/spellcheck/hunspell/glue/mozHunspell.cpp @@ -58,6 +58,8 @@ ******* END LICENSE BLOCK *******/ #include "mozHunspell.h" +#include "mozHunspellFileMgrGlue.h" +#include "mozHunspellFileMgrHost.h" #include "nsReadableUtils.h" #include "nsString.h" #include "nsIObserverService.h" @@ -186,7 +188,10 @@ mozHunspell::SetDictionary(const nsACString& aDictionary) { mDictionary = dict; mAffixFileName = affFileName; - mHunspell = new RLBoxHunspell(affFileName, dictFileName); + RegisterHunspellCallbacks( + mozHunspellCallbacks::CreateFilemgr, mozHunspellCallbacks::GetLine, + mozHunspellCallbacks::GetLineNum, mozHunspellCallbacks::DestructFilemgr); + mHunspell = new Hunspell(affFileName.get(), dictFileName.get()); if (!mHunspell) return NS_ERROR_OUT_OF_MEMORY; auto encoding = diff --git a/extensions/spellcheck/hunspell/glue/mozHunspell.h b/extensions/spellcheck/hunspell/glue/mozHunspell.h index de7c757a68d8..68cba4ae70ec 100644 --- a/extensions/spellcheck/hunspell/glue/mozHunspell.h +++ b/extensions/spellcheck/hunspell/glue/mozHunspell.h @@ -60,7 +60,7 @@ #ifndef mozHunspell_h__ #define mozHunspell_h__ -#include "RLBoxHunspell.h" +#include #include "mozISpellCheckingEngine.h" #include "mozIPersonalDictionary.h" #include "nsString.h" @@ -123,7 +123,7 @@ class mozHunspell final : public mozISpellCheckingEngine, nsCOMArray mDynamicDirectories; nsInterfaceHashtable mDynamicDictionaries; - RLBoxHunspell* mHunspell; + Hunspell* mHunspell; }; #endif diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxGlue.h b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrGlue.h similarity index 63% rename from extensions/spellcheck/hunspell/glue/mozHunspellRLBoxGlue.h rename to extensions/spellcheck/hunspell/glue/mozHunspellFileMgrGlue.h index d84a5ba73930..d3c75dc04c4b 100644 --- a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxGlue.h +++ b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrGlue.h @@ -4,8 +4,8 @@ * 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/. */ -#ifndef mozHunspellRLBoxGlue_h -#define mozHunspellRLBoxGlue_h +#ifndef mozHunspellFileMgrGlue_h +#define mozHunspellFileMgrGlue_h #include @@ -13,30 +13,22 @@ extern "C" { #endif -typedef uint32_t(hunspell_create_filemgr_t)(const char* aFilename); +typedef uint32_t(hunspell_create_filemgr_t)(const char* aFilename, + const char* aKey); typedef bool(hunspell_get_line_t)(uint32_t aFd, char** aLinePtr); typedef int(hunspell_get_line_num_t)(uint32_t aFd); typedef void(hunspell_destruct_filemgr_t)(uint32_t aFd); -typedef uint32_t(hunspell_ToUpperCase_t)(uint32_t aChar); -typedef uint32_t(hunspell_ToLowerCase_t)(uint32_t aChar); -typedef struct cs_info*(hunspell_get_current_cs_t)(const char* es); void RegisterHunspellCallbacks( hunspell_create_filemgr_t* aHunspellCreateFilemgr, hunspell_get_line_t* aHunspellGetLine, hunspell_get_line_num_t* aHunspellGetLine_num, - hunspell_destruct_filemgr_t* aHunspellDestructFilemgr, - hunspell_ToUpperCase_t* aHunspellToUpperCase, - hunspell_ToLowerCase_t* aHunspellToLowerCase, - hunspell_get_current_cs_t* aHunspellGetCurrentCS); + hunspell_destruct_filemgr_t* aHunspellDestructFilemgr); extern hunspell_create_filemgr_t* moz_glue_hunspell_create_filemgr; extern hunspell_get_line_t* moz_glue_hunspell_get_line; extern hunspell_get_line_num_t* moz_glue_hunspell_get_line_num; extern hunspell_destruct_filemgr_t* moz_glue_hunspell_destruct_filemgr; -extern hunspell_ToUpperCase_t* moz_hunspell_ToUpperCase; -extern hunspell_ToLowerCase_t* moz_hunspell_ToLowerCase; -extern hunspell_get_current_cs_t* moz_hunspell_GetCurrentCS; #if defined(__cplusplus) } diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.cpp b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.cpp new file mode 100644 index 000000000000..ce8b2126153a --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.cpp @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include + +#include "mozHunspellFileMgrHost.h" +#include "mozilla/DebugOnly.h" +#include "nsContentUtils.h" +#include "nsIChannel.h" +#include "nsILoadInfo.h" +#include "nsNetUtil.h" + +using namespace mozilla; + +mozHunspellFileMgrHost::mozHunspellFileMgrHost(const char* aFilename, + const char* aKey) { + DebugOnly> result = Open(nsDependentCString(aFilename)); + NS_WARNING_ASSERTION(result.value.isOk(), "Failed to open Hunspell file"); +} + +Result mozHunspellFileMgrHost::Open(const nsACString& aPath) { + nsCOMPtr uri; + MOZ_TRY(NS_NewURI(getter_AddRefs(uri), aPath)); + + nsCOMPtr channel; + MOZ_TRY(NS_NewChannel( + getter_AddRefs(channel), uri, nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_INHERITS_SEC_CONTEXT, + nsIContentPolicy::TYPE_OTHER)); + + MOZ_TRY(channel->Open(getter_AddRefs(mStream))); + return Ok(); +} + +Result mozHunspellFileMgrHost::ReadLine(nsACString& aLine) { + if (!mStream) { + return Err(NS_ERROR_NOT_INITIALIZED); + } + + bool ok; + MOZ_TRY(NS_ReadLine(mStream.get(), &mLineBuffer, aLine, &ok)); + if (!ok) { + mStream = nullptr; + } + + mLineNum++; + return Ok(); +} + +bool mozHunspellFileMgrHost::GetLine(std::string& aResult) { + nsAutoCString line; + auto res = ReadLine(line); + if (res.isErr()) { + return false; + } + + aResult.assign(line.BeginReading(), line.Length()); + return true; +} + +/* static */ +uint32_t mozHunspellCallbacks::sCurrentFreshId = 0; +/* static */ +mozilla::detail::StaticRWLock mozHunspellCallbacks::sFileMgrMapLock; +/* static */ +std::map> + mozHunspellCallbacks::sFileMgrMap; + +/* static */ +uint32_t mozHunspellCallbacks::CreateFilemgr(const char* aFilename, + const char* aKey) { + mozilla::detail::StaticAutoWriteLock lock(sFileMgrMapLock); + uint32_t freshId = GetFreshId(); + sFileMgrMap[freshId] = std::unique_ptr( + new mozHunspellFileMgrHost(aFilename, aKey)); + return freshId; +} + +/* static */ +uint32_t mozHunspellCallbacks::GetFreshId() { + // i is uint64_t to prevent overflow during loop increment which would cause + // an infinite loop + for (uint64_t i = sCurrentFreshId; i < std::numeric_limits::max(); + i++) { + auto it = sFileMgrMap.find(i); + if (it == sFileMgrMap.end()) { + // set sCurrentFreshId to the next (possibly) available id + sCurrentFreshId = i + 1; + return static_cast(i); + } + } + + MOZ_CRASH("Ran out of unique file ids for hunspell dictionaries"); +} + +/* static */ +mozHunspellFileMgrHost& mozHunspellCallbacks::GetMozHunspellFileMgrHost( + uint32_t aFd) { + mozilla::detail::StaticAutoReadLock lock(sFileMgrMapLock); + auto iter = sFileMgrMap.find(aFd); + MOZ_RELEASE_ASSERT(iter != sFileMgrMap.end()); + return *(iter->second.get()); +} + +/* static */ +bool mozHunspellCallbacks::GetLine(uint32_t aFd, char** aLinePtr) { + mozHunspellFileMgrHost& inst = + mozHunspellCallbacks::GetMozHunspellFileMgrHost(aFd); + std::string line; + bool ok = inst.GetLine(line); + if (ok) { + *aLinePtr = static_cast(malloc(line.size() + 1)); + strcpy(*aLinePtr, line.c_str()); + } else { + *aLinePtr = nullptr; + } + return ok; +} + +/* static */ +int mozHunspellCallbacks::GetLineNum(uint32_t aFd) { + mozHunspellFileMgrHost& inst = + mozHunspellCallbacks::GetMozHunspellFileMgrHost(aFd); + int num = inst.GetLineNum(); + return num; +} + +/* static */ +void mozHunspellCallbacks::DestructFilemgr(uint32_t aFd) { + mozilla::detail::StaticAutoWriteLock lock(sFileMgrMapLock); + + auto iter = sFileMgrMap.find(aFd); + if (iter != sFileMgrMap.end()) { + sFileMgrMap.erase(iter); + } +} diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.h b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.h new file mode 100644 index 000000000000..8812416f71c5 --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.h @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozHunspellFileMgrHost_h +#define mozHunspellFileMgrHost_h + +#include +#include +#include +#include +#include + +#include "mozilla/Result.h" +#include "mozilla/ResultExtensions.h" +#include "mozilla/RWLock.h" +#include "nsIInputStream.h" +#include "nsReadLine.h" + +namespace mozilla { + +class mozHunspellFileMgrHost final { + public: + /** + * aFilename must be a local file/jar URI for the file to load. + * + * aKey is the decription key for encrypted Hunzip files, and is + * unsupported. The argument is there solely for compatibility. + */ + explicit mozHunspellFileMgrHost(const char* aFilename, + const char* aKey = nullptr); + ~mozHunspellFileMgrHost() = default; + + bool GetLine(std::string& aResult); + int GetLineNum() const { return mLineNum; } + + private: + mozilla::Result Open(const nsACString& aPath); + + mozilla::Result ReadLine(nsACString& aLine); + + int mLineNum = 0; + nsCOMPtr mStream; + nsLineBuffer mLineBuffer; +}; + +class mozHunspellCallbacks { + public: + // APIs invoked by the sandboxed hunspell file manager + static uint32_t CreateFilemgr(const char* aFilename, const char* aKey); + static bool GetLine(uint32_t aFd, char** aLinePtr); + static int GetLineNum(uint32_t aFd); + static void DestructFilemgr(uint32_t aFd); + + private: + /** + * sFileMgrMap holds a map between unique uint32_t + * integers and mozHunspellFileMgrHost instances + */ + static std::map> + sFileMgrMap; + /** + * Reader-writer lock for the sFileMgrMap + */ + static mozilla::detail::StaticRWLock sFileMgrMapLock; + /** + * Tracks the next possibly unused id for sFileMgrMap + */ + static uint32_t sCurrentFreshId; + /** + * Returns an unused id for sFileMgrMap + */ + static uint32_t GetFreshId(); + /** + * Returns the mozHunspellFileMgrHost for the given uint32_t id + */ + static mozHunspellFileMgrHost& GetMozHunspellFileMgrHost(uint32_t aFd); +}; +} // namespace mozilla + +#endif diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.cpp b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrSandbox.cpp similarity index 67% rename from extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.cpp rename to extensions/spellcheck/hunspell/glue/mozHunspellFileMgrSandbox.cpp index f913b4bc836d..4458877464ef 100644 --- a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.cpp +++ b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrSandbox.cpp @@ -4,12 +4,11 @@ * 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/. */ -#include "mozHunspellRLBoxSandbox.h" -#include "mozHunspellRLBoxGlue.h" +#include "mozHunspellFileMgrSandbox.h" +#include "mozHunspellFileMgrGlue.h" FileMgr::FileMgr(const char* aFilename, const char* aKey) : mFd(0) { - // The key is not used in firefox - mFd = moz_glue_hunspell_create_filemgr(aFilename); + mFd = moz_glue_hunspell_create_filemgr(aFilename, aKey); } bool FileMgr::getline(std::string& aResult) { @@ -32,23 +31,14 @@ hunspell_create_filemgr_t* moz_glue_hunspell_create_filemgr = nullptr; hunspell_get_line_t* moz_glue_hunspell_get_line = nullptr; hunspell_get_line_num_t* moz_glue_hunspell_get_line_num = nullptr; hunspell_destruct_filemgr_t* moz_glue_hunspell_destruct_filemgr = nullptr; -hunspell_ToUpperCase_t* moz_hunspell_ToUpperCase = nullptr; -hunspell_ToLowerCase_t* moz_hunspell_ToLowerCase = nullptr; -hunspell_get_current_cs_t* moz_hunspell_GetCurrentCS = nullptr; void RegisterHunspellCallbacks( hunspell_create_filemgr_t* aHunspellCreateFilemgr, hunspell_get_line_t* aHunspellGetLine, hunspell_get_line_num_t* aHunspellGetLine_num, - hunspell_destruct_filemgr_t* aHunspellDestructFilemgr, - hunspell_ToUpperCase_t* aHunspellToUpperCase, - hunspell_ToLowerCase_t* aHunspellToLowerCase, - hunspell_get_current_cs_t* aHunspellGetCurrentCS) { + hunspell_destruct_filemgr_t* aHunspellDestructFilemgr) { moz_glue_hunspell_create_filemgr = aHunspellCreateFilemgr; moz_glue_hunspell_get_line = aHunspellGetLine; moz_glue_hunspell_get_line_num = aHunspellGetLine_num; moz_glue_hunspell_destruct_filemgr = aHunspellDestructFilemgr; - moz_hunspell_ToUpperCase = aHunspellToUpperCase; - moz_hunspell_ToLowerCase = aHunspellToLowerCase; - moz_hunspell_GetCurrentCS = aHunspellGetCurrentCS; } diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.h b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrSandbox.h similarity index 82% rename from extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.h rename to extensions/spellcheck/hunspell/glue/mozHunspellFileMgrSandbox.h index 9850408807e9..c0434c14ca05 100644 --- a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxSandbox.h +++ b/extensions/spellcheck/hunspell/glue/mozHunspellFileMgrSandbox.h @@ -4,12 +4,17 @@ * 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/. */ -#ifndef mozHunspellRLBoxSandbox_h -#define mozHunspellRLBoxSandbox_h +#ifndef mozHunspellFileMgrSandbox_h +#define mozHunspellFileMgrSandbox_h #include #include +#include "mozilla/Result.h" +#include "mozilla/ResultExtensions.h" +#include "nsIInputStream.h" +#include "nsReadLine.h" + // Note: This class name and lack of namespacing terrible, but are necessary // for Hunspell compatibility. class FileMgr final { @@ -33,4 +38,4 @@ class FileMgr final { uint32_t mFd; }; -#endif // mozHunspellRLBoxSandbox_h +#endif // mozHunspellFileMgrSandbox_h diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.cpp b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.cpp deleted file mode 100644 index e675fa3c8b4b..000000000000 --- a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include - -#include "mozHunspellRLBoxHost.h" -#include "mozilla/DebugOnly.h" -#include "nsContentUtils.h" -#include "nsIChannel.h" -#include "nsILoadInfo.h" -#include "nsNetUtil.h" -#include "nsUnicharUtils.h" - -#include "hunspell_csutil.hxx" - -using namespace mozilla; - -mozHunspellFileMgrHost::mozHunspellFileMgrHost(const nsCString& aFilename) { - DebugOnly> result = Open(aFilename); - NS_WARNING_ASSERTION(result.value.isOk(), "Failed to open Hunspell file"); -} - -Result mozHunspellFileMgrHost::Open(const nsCString& aPath) { - nsCOMPtr uri; - MOZ_TRY(NS_NewURI(getter_AddRefs(uri), aPath)); - - nsCOMPtr channel; - MOZ_TRY(NS_NewChannel( - getter_AddRefs(channel), uri, nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_INHERITS_SEC_CONTEXT, - nsIContentPolicy::TYPE_OTHER)); - - MOZ_TRY(channel->Open(getter_AddRefs(mStream))); - return Ok(); -} - -Result mozHunspellFileMgrHost::ReadLine(nsCString& aLine) { - if (!mStream) { - return Err(NS_ERROR_NOT_INITIALIZED); - } - - bool ok; - MOZ_TRY(NS_ReadLine(mStream.get(), &mLineBuffer, aLine, &ok)); - if (!ok) { - mStream = nullptr; - } - - mLineNum++; - return Ok(); -} - -bool mozHunspellFileMgrHost::GetLine(std::string& aResult) { - nsAutoCString line; - auto res = ReadLine(line); - if (res.isErr()) { - return false; - } - - aResult.assign(line.BeginReading(), line.Length()); - return true; -} - -/* static */ -uint32_t mozHunspellCallbacks::sCurrentFreshId = 0; -/* static */ -mozilla::detail::StaticRWLock mozHunspellCallbacks::sFileMgrMapLock; -/* static */ -std::map> - mozHunspellCallbacks::sFileMgrMap; -/* static */ -std::set mozHunspellCallbacks::sFileMgrAllowList; - -/* static */ -void mozHunspellCallbacks::AllowFile(const nsCString& aFilename) { - mozilla::detail::StaticAutoWriteLock lock(sFileMgrMapLock); - sFileMgrAllowList.insert(aFilename); -} - -/* static */ -void mozHunspellCallbacks::Clear() { - mozilla::detail::StaticAutoWriteLock lock(sFileMgrMapLock); - sCurrentFreshId = 0; - sFileMgrMap.clear(); - sFileMgrAllowList.clear(); -} - -/* static */ -tainted_hunspell mozHunspellCallbacks::CreateFilemgr( - rlbox_sandbox_hunspell& aSandbox, - tainted_hunspell t_aFilename) { - mozilla::detail::StaticAutoWriteLock lock(sFileMgrMapLock); - - return t_aFilename.copy_and_verify_string( - [&](std::unique_ptr aFilename) { - nsCString cFilename = nsDependentCString(aFilename.get()); - - // Ensure that the filename is in the allowlist - auto it = sFileMgrAllowList.find(cFilename); - MOZ_RELEASE_ASSERT(it != sFileMgrAllowList.end()); - - // Get new id - uint32_t freshId = GetFreshId(); - // Save mapping of id to file manager - sFileMgrMap[freshId] = std::unique_ptr( - new mozHunspellFileMgrHost(cFilename)); - - return freshId; - }); -} - -/* static */ -uint32_t mozHunspellCallbacks::GetFreshId() { - // i is uint64_t to prevent overflow during loop increment which would cause - // an infinite loop - for (uint64_t i = sCurrentFreshId; i < std::numeric_limits::max(); - i++) { - auto it = sFileMgrMap.find(i); - if (it == sFileMgrMap.end()) { - // set sCurrentFreshId to the next (possibly) available id - sCurrentFreshId = i + 1; - return static_cast(i); - } - } - - MOZ_CRASH("Ran out of unique file ids for hunspell dictionaries"); -} - -/* static */ -mozHunspellFileMgrHost& mozHunspellCallbacks::GetMozHunspellFileMgrHost( - tainted_hunspell t_aFd) { - mozilla::detail::StaticAutoReadLock lock(sFileMgrMapLock); - uint32_t aFd = t_aFd.copy_and_verify([](uint32_t aFd) { return aFd; }); - auto iter = sFileMgrMap.find(aFd); - MOZ_RELEASE_ASSERT(iter != sFileMgrMap.end()); - return *(iter->second.get()); -} - -/* static */ -tainted_hunspell mozHunspellCallbacks::GetLine( - rlbox_sandbox_hunspell& aSandbox, tainted_hunspell t_aFd, - tainted_hunspell t_aLinePtr) { - mozHunspellFileMgrHost& inst = - mozHunspellCallbacks::GetMozHunspellFileMgrHost(t_aFd); - std::string line; - bool ok = inst.GetLine(line); - if (ok) { - // copy the line into the sandbox - size_t size = line.size() + 1; - tainted_hunspell t_line = aSandbox.malloc_in_sandbox(size); - MOZ_RELEASE_ASSERT(t_line); - rlbox::memcpy(aSandbox, t_line, line.c_str(), size); - *t_aLinePtr = t_line; - } else { - *t_aLinePtr = nullptr; - } - return ok; -} - -/* static */ -tainted_hunspell mozHunspellCallbacks::GetLineNum( - rlbox_sandbox_hunspell& aSandbox, tainted_hunspell t_aFd) { - mozHunspellFileMgrHost& inst = - mozHunspellCallbacks::GetMozHunspellFileMgrHost(t_aFd); - int num = inst.GetLineNum(); - return num; -} - -/* static */ -void mozHunspellCallbacks::DestructFilemgr(rlbox_sandbox_hunspell& aSandbox, - tainted_hunspell t_aFd) { - mozilla::detail::StaticAutoWriteLock lock(sFileMgrMapLock); - uint32_t aFd = t_aFd.copy_and_verify([](uint32_t aFd) { return aFd; }); - - auto iter = sFileMgrMap.find(aFd); - if (iter != sFileMgrMap.end()) { - sFileMgrMap.erase(iter); - } -} - -// Callbacks for using Firefox's encoding instead of hunspell's - -/* static */ -tainted_hunspell mozHunspellCallbacks::ToUpperCase( - rlbox_sandbox_hunspell& aSandbox, tainted_hunspell t_aChar) { - uint32_t aChar = - t_aChar.copy_and_verify([](uint32_t aChar) { return aChar; }); - return ::ToUpperCase(aChar); -} - -/* static */ -tainted_hunspell mozHunspellCallbacks::ToLowerCase( - rlbox_sandbox_hunspell& aSandbox, tainted_hunspell t_aChar) { - uint32_t aChar = - t_aChar.copy_and_verify([](uint32_t aChar) { return aChar; }); - return ::ToLowerCase(aChar); -} - -/* static */ tainted_hunspell -mozHunspellCallbacks::GetCurrentCS(rlbox_sandbox_hunspell& aSandbox, - tainted_hunspell t_es) { - tainted_hunspell t_ccs = - aSandbox.malloc_in_sandbox(256); - MOZ_RELEASE_ASSERT(t_ccs); - return t_es.copy_and_verify_string([&](std::unique_ptr es) { - struct cs_info* ccs = hunspell_get_current_cs(es.get()); - rlbox::memcpy(aSandbox, t_ccs, ccs, sizeof(struct cs_info) * 256); - delete[] ccs; - return t_ccs; - }); -} diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.h b/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.h deleted file mode 100644 index b274bc20be16..000000000000 --- a/extensions/spellcheck/hunspell/glue/mozHunspellRLBoxHost.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef mozHunspellRLBoxHost_h -#define mozHunspellRLBoxHost_h - -#include -#include -#include -#include -#include -#include - -#include "RLBoxHunspell.h" -#include "mozilla/Result.h" -#include "mozilla/ResultExtensions.h" -#include "mozilla/RWLock.h" -#include "nsIInputStream.h" -#include "nsReadLine.h" - -namespace mozilla { - -class mozHunspellFileMgrHost final { - public: - /** - * aFilename must be a local file/jar URI for the file to load. - */ - explicit mozHunspellFileMgrHost(const nsCString& aFilename); - ~mozHunspellFileMgrHost() = default; - - bool GetLine(std::string& aResult); - int GetLineNum() const { return mLineNum; } - - private: - mozilla::Result Open(const nsCString& aPath); - - mozilla::Result ReadLine(nsCString& aLine); - - int mLineNum = 0; - nsCOMPtr mStream; - nsLineBuffer mLineBuffer; -}; - -class mozHunspellCallbacks { - public: - // APIs invoked by the sandboxed hunspell file manager - static tainted_hunspell CreateFilemgr( - rlbox_sandbox_hunspell& aSandbox, - tainted_hunspell t_aFilename); - static tainted_hunspell GetLine(rlbox_sandbox_hunspell& aSandbox, - tainted_hunspell t_aFd, - tainted_hunspell t_aLinePtr); - static tainted_hunspell GetLineNum(rlbox_sandbox_hunspell& aSandbox, - tainted_hunspell t_aFd); - static void DestructFilemgr(rlbox_sandbox_hunspell& aSandbox, - tainted_hunspell t_aFd); - - // APIs necessary for hunspell UTF encoding - static tainted_hunspell ToUpperCase( - rlbox_sandbox_hunspell& aSandbox, tainted_hunspell t_aChar); - static tainted_hunspell ToLowerCase( - rlbox_sandbox_hunspell& aSandbox, tainted_hunspell t_aChar); - static tainted_hunspell GetCurrentCS( - rlbox_sandbox_hunspell& aSandbox, tainted_hunspell t_es); - - protected: - // API called by RLBox - - /** - * Add filename to allow list. - */ - static void AllowFile(const nsCString& aFilename); - friend RLBoxHunspell::RLBoxHunspell(const nsAutoCString& affpath, - const nsAutoCString& dpath); - /** - * Clear allow list and map of hunspell file managers. - */ - static void Clear(); - friend RLBoxHunspell::~RLBoxHunspell(); - - private: - /** - * sFileMgrMap holds a map between unique uint32_t - * integers and mozHunspellFileMgrHost instances - */ - static std::map> - sFileMgrMap; - - /** - * sFileMgrAllowList contains the filenames of the dictionary files hunspell - * is allowed to open - */ - static std::set sFileMgrAllowList; - /** - * Reader-writer lock for the sFileMgrMap - */ - static mozilla::detail::StaticRWLock sFileMgrMapLock; - /** - * Tracks the next possibly unused id for sFileMgrMap - */ - static uint32_t sCurrentFreshId; - /** - * Returns an unused id for sFileMgrMap - */ - static uint32_t GetFreshId(); - /** - * Returns the mozHunspellFileMgrHost for the given uint32_t id - */ - static mozHunspellFileMgrHost& GetMozHunspellFileMgrHost( - tainted_hunspell t_aFd); -}; -} // namespace mozilla - -#endif diff --git a/extensions/spellcheck/hunspell/patches/bug1410214.patch b/extensions/spellcheck/hunspell/patches/bug1410214.patch index 04452f1f527d..a6e45140a9f9 100644 --- a/extensions/spellcheck/hunspell/patches/bug1410214.patch +++ b/extensions/spellcheck/hunspell/patches/bug1410214.patch @@ -154,7 +154,7 @@ diff --git a/extensions/spellcheck/hunspell/src/filemgr.hxx b/extensions/spellch - private: - FileMgr(const FileMgr&); - FileMgr& operator=(const FileMgr&); -+#include "mozHunspellRLBoxSandbox.h" ++#include "mozHunspellFileMgrSandbox.h" - protected: - std::ifstream fin; diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx index 1216ce5a1153..014ddaecbca1 100644 --- a/extensions/spellcheck/hunspell/src/csutil.cxx +++ b/extensions/spellcheck/hunspell/src/csutil.cxx @@ -95,7 +95,11 @@ #endif #ifdef MOZILLA_CLIENT -#include "mozHunspellRLBoxGlue.h" +#include "nsCOMPtr.h" +#include "nsUnicharUtils.h" +#include "mozilla/Encoding.h" + +using namespace mozilla; #endif struct unicode_info2 { @@ -2278,8 +2282,91 @@ struct cs_info* get_current_cs(const std::string& es) { return ccs; } #else +// XXX This function was rewritten for mozilla. Instead of storing the +// conversion tables static in this file, create them when needed +// with help the mozilla backend. struct cs_info* get_current_cs(const std::string& es) { - return moz_hunspell_GetCurrentCS(es.c_str()); + struct cs_info* ccs = new cs_info[256]; + // Initialze the array with dummy data so that we wouldn't need + // to return null in case of failures. + for (int i = 0; i <= 0xff; ++i) { + ccs[i].ccase = false; + ccs[i].clower = i; + ccs[i].cupper = i; + } + + auto encoding = Encoding::ForLabelNoReplacement(es); + if (!encoding) { + return ccs; + } + auto encoder = encoding->NewEncoder(); + auto decoder = encoding->NewDecoderWithoutBOMHandling(); + + for (unsigned int i = 0; i <= 0xff; ++i) { + bool success = false; + // We want to find the upper/lowercase equivalents of each byte + // in this 1-byte character encoding. Call our encoding/decoding + // APIs separately for each byte since they may reject some of the + // bytes, and we want to handle errors separately for each byte. + uint8_t lower, upper; + do { + if (i == 0) + break; + uint8_t source = uint8_t(i); + char16_t uni[2]; + char16_t uniCased; + uint8_t destination[4]; + auto src1 = Span(&source, 1); + auto dst1 = Span(uni); + auto src2 = Span(&uniCased, 1); + auto dst2 = Span(destination); + + uint32_t result; + size_t read; + size_t written; + Tie(result, read, written) = + decoder->DecodeToUTF16WithoutReplacement(src1, dst1, true); + if (result != kInputEmpty || read != 1 || written != 1) { + break; + } + + uniCased = ToLowerCase(uni[0]); + Tie(result, read, written) = + encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true); + if (result != kInputEmpty || read != 1 || written != 1) { + break; + } + lower = destination[0]; + + uniCased = ToUpperCase(uni[0]); + Tie(result, read, written) = + encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true); + if (result != kInputEmpty || read != 1 || written != 1) { + break; + } + upper = destination[0]; + + success = true; + } while (0); + + encoding->NewEncoderInto(*encoder); + encoding->NewDecoderWithoutBOMHandlingInto(*decoder); + + if (success) { + ccs[i].cupper = upper; + ccs[i].clower = lower; + } else { + ccs[i].cupper = i; + ccs[i].clower = i; + } + + if (ccs[i].clower != (unsigned char)i) + ccs[i].ccase = true; + else + ccs[i].ccase = false; + } + + return ccs; } #endif @@ -2373,7 +2460,7 @@ unsigned short unicodetoupper(unsigned short c, int langnum) { return static_cast(u_toupper(c)); #else #ifdef MOZILLA_CLIENT - return moz_hunspell_ToUpperCase((char16_t)c); + return ToUpperCase((char16_t)c); #else return (utf_tbl) ? utf_tbl[c].cupper : c; #endif @@ -2390,7 +2477,7 @@ unsigned short unicodetolower(unsigned short c, int langnum) { return static_cast(u_tolower(c)); #else #ifdef MOZILLA_CLIENT - return moz_hunspell_ToLowerCase((char16_t)c); + return ToLowerCase((char16_t)c); #else return (utf_tbl) ? utf_tbl[c].clower : c; #endif diff --git a/extensions/spellcheck/hunspell/src/csutil.hxx b/extensions/spellcheck/hunspell/src/csutil.hxx index 3ad400495ae9..739e2299f390 100644 --- a/extensions/spellcheck/hunspell/src/csutil.hxx +++ b/extensions/spellcheck/hunspell/src/csutil.hxx @@ -82,6 +82,10 @@ #include "w_char.hxx" #include "htypes.hxx" +#ifdef MOZILLA_CLIENT +#include "nscore.h" // for mozalloc headers +#endif + // casing #define NOCAP 0 #define INITCAP 1 diff --git a/extensions/spellcheck/hunspell/src/filemgr.hxx b/extensions/spellcheck/hunspell/src/filemgr.hxx index 7298bc8676fc..d60f39a620bc 100644 --- a/extensions/spellcheck/hunspell/src/filemgr.hxx +++ b/extensions/spellcheck/hunspell/src/filemgr.hxx @@ -72,6 +72,6 @@ #ifndef FILEMGR_HXX_ #define FILEMGR_HXX_ -#include "mozHunspellRLBoxSandbox.h" +#include "mozHunspellFileMgrSandbox.h" #endif diff --git a/extensions/spellcheck/hunspell/src/moz.build b/extensions/spellcheck/hunspell/src/moz.build index 1316bf472722..0484398d9846 100644 --- a/extensions/spellcheck/hunspell/src/moz.build +++ b/extensions/spellcheck/hunspell/src/moz.build @@ -4,8 +4,8 @@ # 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/. -all_sources = [ - '../glue/mozHunspellRLBoxSandbox.cpp', +UNIFIED_SOURCES += [ + '../glue/mozHunspellFileMgrSandbox.cpp', 'affentry.cxx', 'affixmgr.cxx', 'csutil.cxx', @@ -16,13 +16,6 @@ all_sources = [ 'suggestmgr.cxx', ] -UNIFIED_SOURCES += all_sources - -if CONFIG['MOZ_WASM_SANDBOXING_HUNSPELL']: - SANDBOXED_WASM_LIBRARY_NAME = 'hunspellwasm' - WASM_DEFINES['MOZILLA_CLIENT'] = True - WASM_SOURCES += all_sources - DEFINES['HUNSPELL_STATIC'] = True FINAL_LIBRARY = 'xul' diff --git a/ipc/glue/LibrarySandboxPreload.cpp b/ipc/glue/LibrarySandboxPreload.cpp index 48797c9d61f3..a49b8458b34b 100644 --- a/ipc/glue/LibrarySandboxPreload.cpp +++ b/ipc/glue/LibrarySandboxPreload.cpp @@ -51,11 +51,6 @@ nsAutoCString GetSandboxedOggPath() { nsLiteralCString(MOZ_DLL_PREFIX "oggwasm" MOZ_DLL_SUFFIX)); } -nsAutoCString GetSandboxedHunspellPath() { - return GetSandboxedPath( - nsLiteralCString(MOZ_DLL_PREFIX "hunspellwasm" MOZ_DLL_SUFFIX)); -} - PRLibrary* PreloadLibrary(const nsAutoCString& path) { PRLibSpec libSpec; libSpec.type = PR_LibSpec_Pathname; @@ -80,11 +75,6 @@ void PreloadSandboxedDynamicLibraries() { MOZ_CRASH("Library preload failure: Failed to load libogg\n"); } # endif -# if defined(MOZ_WASM_SANDBOXING_HUNSPELL) - if (!PreloadLibrary(GetSandboxedHunspellPath())) { - MOZ_CRASH("Library preload failure: Failed to load libhunspell\n"); - } -# endif #endif } diff --git a/ipc/glue/LibrarySandboxPreload.h b/ipc/glue/LibrarySandboxPreload.h index 8e185e8d0eed..0193f2f8a68c 100644 --- a/ipc/glue/LibrarySandboxPreload.h +++ b/ipc/glue/LibrarySandboxPreload.h @@ -12,7 +12,6 @@ namespace mozilla { namespace ipc { nsAutoCString GetSandboxedGraphitePath(); nsAutoCString GetSandboxedOggPath(); -nsAutoCString GetSandboxedHunspellPath(); void PreloadSandboxedDynamicLibraries(); } // namespace ipc } // namespace mozilla diff --git a/toolkit/moz.configure b/toolkit/moz.configure index 7d2724e4dd8e..e758ab3b9265 100644 --- a/toolkit/moz.configure +++ b/toolkit/moz.configure @@ -2045,7 +2045,6 @@ def wasm_sandboxing_libraries(): return ( "graphite", "ogg", - "hunspell", )