forked from mirrors/gecko-dev
Backed out 2 changesets (bug 1653659) for Build bustage in builds/worker/workspace/obj-build/dist/include/mozilla/rlbox/rlbox_type_traits.hpp. CLOSED TREE
Backed out changeset 783310e1f5b8 (bug 1653659) Backed out changeset 876dfd999d65 (bug 1653659)
This commit is contained in:
parent
e3097163dd
commit
869d44f53c
24 changed files with 347 additions and 907 deletions
|
|
@ -118,9 +118,6 @@
|
||||||
#ifdef MOZ_WASM_SANDBOXING_OGG
|
#ifdef MOZ_WASM_SANDBOXING_OGG
|
||||||
@BINPATH@/@DLL_PREFIX@oggwasm@DLL_SUFFIX@
|
@BINPATH@/@DLL_PREFIX@oggwasm@DLL_SUFFIX@
|
||||||
#endif
|
#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
|
; 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
|
; build because we haven't run the relevant parts of configure, so we guess
|
||||||
|
|
|
||||||
|
|
@ -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<char*> allocStrInSandbox(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox, const nsAutoCString& str) {
|
|
||||||
size_t size = str.Length() + 1;
|
|
||||||
tainted_hunspell<char*> t_str = aSandbox.malloc_in_sandbox<char>(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<char*> allocStrInSandbox(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox, const std::string& str) {
|
|
||||||
size_t size = str.size() + 1;
|
|
||||||
tainted_hunspell<char*> t_str = aSandbox.malloc_in_sandbox<char>(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<char*> t_affpath = allocStrInSandbox(mSandbox, affpath);
|
|
||||||
tainted_hunspell<char*> t_dpath = allocStrInSandbox(mSandbox, dpath);
|
|
||||||
|
|
||||||
// Create handle
|
|
||||||
mHandle = mSandbox.invoke_sandbox_function(
|
|
||||||
Hunspell_create, rlbox::sandbox_const_cast<const char*>(t_affpath),
|
|
||||||
rlbox::sandbox_const_cast<const char*>(t_dpath));
|
|
||||||
MOZ_RELEASE_ASSERT(mHandle);
|
|
||||||
|
|
||||||
mSandbox.free_in_sandbox(t_dpath);
|
|
||||||
mSandbox.free_in_sandbox(t_affpath);
|
|
||||||
|
|
||||||
// Get dictionary encoding
|
|
||||||
tainted_hunspell<char*> t_enc =
|
|
||||||
mSandbox.invoke_sandbox_function(Hunspell_get_dic_encoding, mHandle);
|
|
||||||
t_enc.copy_and_verify_string([&](std::unique_ptr<char[]> 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<char*> t_word = allocStrInSandbox(mSandbox, stdWord);
|
|
||||||
|
|
||||||
// Check word
|
|
||||||
int good = mSandbox
|
|
||||||
.invoke_sandbox_function(
|
|
||||||
Hunspell_spell, mHandle,
|
|
||||||
rlbox::sandbox_const_cast<const char*>(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<std::string> RLBoxHunspell::suggest(const std::string& stdWord) {
|
|
||||||
// Copy word into the sandbox
|
|
||||||
tainted_hunspell<char*> t_word = allocStrInSandbox(mSandbox, stdWord);
|
|
||||||
|
|
||||||
// Allocate suggestion list in the sandbox
|
|
||||||
tainted_hunspell<char***> t_slst = mSandbox.malloc_in_sandbox<char**>();
|
|
||||||
*t_slst = nullptr;
|
|
||||||
|
|
||||||
// Get suggestions
|
|
||||||
int nr = mSandbox
|
|
||||||
.invoke_sandbox_function(
|
|
||||||
Hunspell_suggest, mHandle, t_slst,
|
|
||||||
rlbox::sandbox_const_cast<const char*>(t_word))
|
|
||||||
.copy_and_verify([](int nr) {
|
|
||||||
MOZ_RELEASE_ASSERT(nr >= 0);
|
|
||||||
return nr;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Copy suggestions from sandbox
|
|
||||||
std::vector<std::string> suggestions;
|
|
||||||
suggestions.reserve(nr);
|
|
||||||
for (int i = 0; i < nr; i++) {
|
|
||||||
tainted_hunspell<char*> t_sug = (*t_slst)[i];
|
|
||||||
MOZ_RELEASE_ASSERT(t_sug);
|
|
||||||
t_sug.copy_and_verify_string([&](std::unique_ptr<char[]> 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;
|
|
||||||
}
|
|
||||||
|
|
@ -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 <hunspell.h>
|
|
||||||
#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<std::string> suggest(const std::string& word);
|
|
||||||
|
|
||||||
private:
|
|
||||||
rlbox_sandbox_hunspell mSandbox;
|
|
||||||
sandbox_callback_hunspell<hunspell_create_filemgr_t*> mCreateFilemgr;
|
|
||||||
sandbox_callback_hunspell<hunspell_get_line_t*> mGetLine;
|
|
||||||
sandbox_callback_hunspell<hunspell_get_line_num_t*> mGetLineNum;
|
|
||||||
sandbox_callback_hunspell<hunspell_destruct_filemgr_t*> mDestructFilemgr;
|
|
||||||
sandbox_callback_hunspell<hunspell_ToUpperCase_t*> mHunspellToUpperCase;
|
|
||||||
sandbox_callback_hunspell<hunspell_ToLowerCase_t*> mHunspellToLowerCase;
|
|
||||||
sandbox_callback_hunspell<hunspell_get_current_cs_t*> mHunspellGetCurrentCS;
|
|
||||||
tainted_hunspell<Hunhandle*> mHandle;
|
|
||||||
std::string mDicEncoding;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -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 <stddef.h>
|
|
||||||
#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<rlbox_hunspell_sandbox_type>;
|
|
||||||
template <typename T>
|
|
||||||
using sandbox_callback_hunspell =
|
|
||||||
rlbox::sandbox_callback<T, rlbox_hunspell_sandbox_type>;
|
|
||||||
template <typename T>
|
|
||||||
using tainted_hunspell = rlbox::tainted<T, rlbox_hunspell_sandbox_type>;
|
|
||||||
template <typename T>
|
|
||||||
using tainted_opaque_hunspell =
|
|
||||||
rlbox::tainted_opaque<T, rlbox_hunspell_sandbox_type>;
|
|
||||||
template <typename T>
|
|
||||||
using tainted_volatile_hunspell =
|
|
||||||
rlbox::tainted_volatile<T, rlbox_hunspell_sandbox_type>;
|
|
||||||
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
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -5,12 +5,10 @@
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
"hunspell_csutil.cxx",
|
|
||||||
"mozHunspell.cpp",
|
"mozHunspell.cpp",
|
||||||
"mozHunspellRLBoxHost.cpp",
|
"mozHunspellFileMgrHost.cpp",
|
||||||
"RemoteSpellCheckEngineChild.cpp",
|
"RemoteSpellCheckEngineChild.cpp",
|
||||||
"RemoteSpellCheckEngineParent.cpp",
|
"RemoteSpellCheckEngineParent.cpp",
|
||||||
"RLBoxHunspell.cpp",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
DEFINES["HUNSPELL_STATIC"] = True
|
DEFINES["HUNSPELL_STATIC"] = True
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,8 @@
|
||||||
******* END LICENSE BLOCK *******/
|
******* END LICENSE BLOCK *******/
|
||||||
|
|
||||||
#include "mozHunspell.h"
|
#include "mozHunspell.h"
|
||||||
|
#include "mozHunspellFileMgrGlue.h"
|
||||||
|
#include "mozHunspellFileMgrHost.h"
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
|
|
@ -186,7 +188,10 @@ mozHunspell::SetDictionary(const nsACString& aDictionary) {
|
||||||
mDictionary = dict;
|
mDictionary = dict;
|
||||||
mAffixFileName = affFileName;
|
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;
|
if (!mHunspell) return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
auto encoding =
|
auto encoding =
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
#ifndef mozHunspell_h__
|
#ifndef mozHunspell_h__
|
||||||
#define mozHunspell_h__
|
#define mozHunspell_h__
|
||||||
|
|
||||||
#include "RLBoxHunspell.h"
|
#include <hunspell.hxx>
|
||||||
#include "mozISpellCheckingEngine.h"
|
#include "mozISpellCheckingEngine.h"
|
||||||
#include "mozIPersonalDictionary.h"
|
#include "mozIPersonalDictionary.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
|
@ -123,7 +123,7 @@ class mozHunspell final : public mozISpellCheckingEngine,
|
||||||
nsCOMArray<nsIFile> mDynamicDirectories;
|
nsCOMArray<nsIFile> mDynamicDirectories;
|
||||||
nsInterfaceHashtable<nsStringHashKey, nsIURI> mDynamicDictionaries;
|
nsInterfaceHashtable<nsStringHashKey, nsIURI> mDynamicDictionaries;
|
||||||
|
|
||||||
RLBoxHunspell* mHunspell;
|
Hunspell* mHunspell;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef mozHunspellRLBoxGlue_h
|
#ifndef mozHunspellFileMgrGlue_h
|
||||||
#define mozHunspellRLBoxGlue_h
|
#define mozHunspellFileMgrGlue_h
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
@ -13,30 +13,22 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 bool(hunspell_get_line_t)(uint32_t aFd, char** aLinePtr);
|
||||||
typedef int(hunspell_get_line_num_t)(uint32_t aFd);
|
typedef int(hunspell_get_line_num_t)(uint32_t aFd);
|
||||||
typedef void(hunspell_destruct_filemgr_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(
|
void RegisterHunspellCallbacks(
|
||||||
hunspell_create_filemgr_t* aHunspellCreateFilemgr,
|
hunspell_create_filemgr_t* aHunspellCreateFilemgr,
|
||||||
hunspell_get_line_t* aHunspellGetLine,
|
hunspell_get_line_t* aHunspellGetLine,
|
||||||
hunspell_get_line_num_t* aHunspellGetLine_num,
|
hunspell_get_line_num_t* aHunspellGetLine_num,
|
||||||
hunspell_destruct_filemgr_t* aHunspellDestructFilemgr,
|
hunspell_destruct_filemgr_t* aHunspellDestructFilemgr);
|
||||||
hunspell_ToUpperCase_t* aHunspellToUpperCase,
|
|
||||||
hunspell_ToLowerCase_t* aHunspellToLowerCase,
|
|
||||||
hunspell_get_current_cs_t* aHunspellGetCurrentCS);
|
|
||||||
|
|
||||||
extern hunspell_create_filemgr_t* moz_glue_hunspell_create_filemgr;
|
extern hunspell_create_filemgr_t* moz_glue_hunspell_create_filemgr;
|
||||||
extern hunspell_get_line_t* moz_glue_hunspell_get_line;
|
extern hunspell_get_line_t* moz_glue_hunspell_get_line;
|
||||||
extern hunspell_get_line_num_t* moz_glue_hunspell_get_line_num;
|
extern hunspell_get_line_num_t* moz_glue_hunspell_get_line_num;
|
||||||
extern hunspell_destruct_filemgr_t* moz_glue_hunspell_destruct_filemgr;
|
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)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
139
extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.cpp
Normal file
139
extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.cpp
Normal file
|
|
@ -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 <limits>
|
||||||
|
|
||||||
|
#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<Ok, nsresult>> result = Open(nsDependentCString(aFilename));
|
||||||
|
NS_WARNING_ASSERTION(result.value.isOk(), "Failed to open Hunspell file");
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<Ok, nsresult> mozHunspellFileMgrHost::Open(const nsACString& aPath) {
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
MOZ_TRY(NS_NewURI(getter_AddRefs(uri), aPath));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIChannel> 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<Ok, nsresult> 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<uint32_t, std::unique_ptr<mozHunspellFileMgrHost>>
|
||||||
|
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<mozHunspellFileMgrHost>(
|
||||||
|
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<uint32_t>::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<uint32_t>(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<char*>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
83
extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.h
Normal file
83
extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.h
Normal file
|
|
@ -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 <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#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<mozilla::Ok, nsresult> Open(const nsACString& aPath);
|
||||||
|
|
||||||
|
mozilla::Result<mozilla::Ok, nsresult> ReadLine(nsACString& aLine);
|
||||||
|
|
||||||
|
int mLineNum = 0;
|
||||||
|
nsCOMPtr<nsIInputStream> mStream;
|
||||||
|
nsLineBuffer<char> 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<uint32_t, std::unique_ptr<mozHunspellFileMgrHost>>
|
||||||
|
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
|
||||||
|
|
@ -4,12 +4,11 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "mozHunspellRLBoxSandbox.h"
|
#include "mozHunspellFileMgrSandbox.h"
|
||||||
#include "mozHunspellRLBoxGlue.h"
|
#include "mozHunspellFileMgrGlue.h"
|
||||||
|
|
||||||
FileMgr::FileMgr(const char* aFilename, const char* aKey) : mFd(0) {
|
FileMgr::FileMgr(const char* aFilename, const char* aKey) : mFd(0) {
|
||||||
// The key is not used in firefox
|
mFd = moz_glue_hunspell_create_filemgr(aFilename, aKey);
|
||||||
mFd = moz_glue_hunspell_create_filemgr(aFilename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileMgr::getline(std::string& aResult) {
|
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_t* moz_glue_hunspell_get_line = nullptr;
|
||||||
hunspell_get_line_num_t* moz_glue_hunspell_get_line_num = nullptr;
|
hunspell_get_line_num_t* moz_glue_hunspell_get_line_num = nullptr;
|
||||||
hunspell_destruct_filemgr_t* moz_glue_hunspell_destruct_filemgr = 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(
|
void RegisterHunspellCallbacks(
|
||||||
hunspell_create_filemgr_t* aHunspellCreateFilemgr,
|
hunspell_create_filemgr_t* aHunspellCreateFilemgr,
|
||||||
hunspell_get_line_t* aHunspellGetLine,
|
hunspell_get_line_t* aHunspellGetLine,
|
||||||
hunspell_get_line_num_t* aHunspellGetLine_num,
|
hunspell_get_line_num_t* aHunspellGetLine_num,
|
||||||
hunspell_destruct_filemgr_t* aHunspellDestructFilemgr,
|
hunspell_destruct_filemgr_t* aHunspellDestructFilemgr) {
|
||||||
hunspell_ToUpperCase_t* aHunspellToUpperCase,
|
|
||||||
hunspell_ToLowerCase_t* aHunspellToLowerCase,
|
|
||||||
hunspell_get_current_cs_t* aHunspellGetCurrentCS) {
|
|
||||||
moz_glue_hunspell_create_filemgr = aHunspellCreateFilemgr;
|
moz_glue_hunspell_create_filemgr = aHunspellCreateFilemgr;
|
||||||
moz_glue_hunspell_get_line = aHunspellGetLine;
|
moz_glue_hunspell_get_line = aHunspellGetLine;
|
||||||
moz_glue_hunspell_get_line_num = aHunspellGetLine_num;
|
moz_glue_hunspell_get_line_num = aHunspellGetLine_num;
|
||||||
moz_glue_hunspell_destruct_filemgr = aHunspellDestructFilemgr;
|
moz_glue_hunspell_destruct_filemgr = aHunspellDestructFilemgr;
|
||||||
moz_hunspell_ToUpperCase = aHunspellToUpperCase;
|
|
||||||
moz_hunspell_ToLowerCase = aHunspellToLowerCase;
|
|
||||||
moz_hunspell_GetCurrentCS = aHunspellGetCurrentCS;
|
|
||||||
}
|
}
|
||||||
|
|
@ -4,12 +4,17 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef mozHunspellRLBoxSandbox_h
|
#ifndef mozHunspellFileMgrSandbox_h
|
||||||
#define mozHunspellRLBoxSandbox_h
|
#define mozHunspellFileMgrSandbox_h
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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
|
// Note: This class name and lack of namespacing terrible, but are necessary
|
||||||
// for Hunspell compatibility.
|
// for Hunspell compatibility.
|
||||||
class FileMgr final {
|
class FileMgr final {
|
||||||
|
|
@ -33,4 +38,4 @@ class FileMgr final {
|
||||||
uint32_t mFd;
|
uint32_t mFd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // mozHunspellRLBoxSandbox_h
|
#endif // mozHunspellFileMgrSandbox_h
|
||||||
|
|
@ -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 <limits>
|
|
||||||
|
|
||||||
#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<Ok, nsresult>> result = Open(aFilename);
|
|
||||||
NS_WARNING_ASSERTION(result.value.isOk(), "Failed to open Hunspell file");
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<Ok, nsresult> mozHunspellFileMgrHost::Open(const nsCString& aPath) {
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
|
||||||
MOZ_TRY(NS_NewURI(getter_AddRefs(uri), aPath));
|
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> 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<Ok, nsresult> 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<uint32_t, std::unique_ptr<mozHunspellFileMgrHost>>
|
|
||||||
mozHunspellCallbacks::sFileMgrMap;
|
|
||||||
/* static */
|
|
||||||
std::set<nsCString> 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<uint32_t> mozHunspellCallbacks::CreateFilemgr(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox,
|
|
||||||
tainted_hunspell<const char*> t_aFilename) {
|
|
||||||
mozilla::detail::StaticAutoWriteLock lock(sFileMgrMapLock);
|
|
||||||
|
|
||||||
return t_aFilename.copy_and_verify_string(
|
|
||||||
[&](std::unique_ptr<char[]> 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<mozHunspellFileMgrHost>(
|
|
||||||
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<uint32_t>::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<uint32_t>(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_CRASH("Ran out of unique file ids for hunspell dictionaries");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */
|
|
||||||
mozHunspellFileMgrHost& mozHunspellCallbacks::GetMozHunspellFileMgrHost(
|
|
||||||
tainted_hunspell<uint32_t> 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<bool> mozHunspellCallbacks::GetLine(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aFd,
|
|
||||||
tainted_hunspell<char**> 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<char*> t_line = aSandbox.malloc_in_sandbox<char>(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<int> mozHunspellCallbacks::GetLineNum(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aFd) {
|
|
||||||
mozHunspellFileMgrHost& inst =
|
|
||||||
mozHunspellCallbacks::GetMozHunspellFileMgrHost(t_aFd);
|
|
||||||
int num = inst.GetLineNum();
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */
|
|
||||||
void mozHunspellCallbacks::DestructFilemgr(rlbox_sandbox_hunspell& aSandbox,
|
|
||||||
tainted_hunspell<uint32_t> 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<uint32_t> mozHunspellCallbacks::ToUpperCase(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aChar) {
|
|
||||||
uint32_t aChar =
|
|
||||||
t_aChar.copy_and_verify([](uint32_t aChar) { return aChar; });
|
|
||||||
return ::ToUpperCase(aChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */
|
|
||||||
tainted_hunspell<uint32_t> mozHunspellCallbacks::ToLowerCase(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aChar) {
|
|
||||||
uint32_t aChar =
|
|
||||||
t_aChar.copy_and_verify([](uint32_t aChar) { return aChar; });
|
|
||||||
return ::ToLowerCase(aChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ tainted_hunspell<struct cs_info*>
|
|
||||||
mozHunspellCallbacks::GetCurrentCS(rlbox_sandbox_hunspell& aSandbox,
|
|
||||||
tainted_hunspell<const char*> t_es) {
|
|
||||||
tainted_hunspell<struct cs_info*> t_ccs =
|
|
||||||
aSandbox.malloc_in_sandbox<struct cs_info>(256);
|
|
||||||
MOZ_RELEASE_ASSERT(t_ccs);
|
|
||||||
return t_es.copy_and_verify_string([&](std::unique_ptr<char[]> 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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -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 <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
|
||||||
#include <set>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#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<mozilla::Ok, nsresult> Open(const nsCString& aPath);
|
|
||||||
|
|
||||||
mozilla::Result<mozilla::Ok, nsresult> ReadLine(nsCString& aLine);
|
|
||||||
|
|
||||||
int mLineNum = 0;
|
|
||||||
nsCOMPtr<nsIInputStream> mStream;
|
|
||||||
nsLineBuffer<char> mLineBuffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
class mozHunspellCallbacks {
|
|
||||||
public:
|
|
||||||
// APIs invoked by the sandboxed hunspell file manager
|
|
||||||
static tainted_hunspell<uint32_t> CreateFilemgr(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox,
|
|
||||||
tainted_hunspell<const char*> t_aFilename);
|
|
||||||
static tainted_hunspell<bool> GetLine(rlbox_sandbox_hunspell& aSandbox,
|
|
||||||
tainted_hunspell<uint32_t> t_aFd,
|
|
||||||
tainted_hunspell<char**> t_aLinePtr);
|
|
||||||
static tainted_hunspell<int> GetLineNum(rlbox_sandbox_hunspell& aSandbox,
|
|
||||||
tainted_hunspell<uint32_t> t_aFd);
|
|
||||||
static void DestructFilemgr(rlbox_sandbox_hunspell& aSandbox,
|
|
||||||
tainted_hunspell<uint32_t> t_aFd);
|
|
||||||
|
|
||||||
// APIs necessary for hunspell UTF encoding
|
|
||||||
static tainted_hunspell<uint32_t> ToUpperCase(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aChar);
|
|
||||||
static tainted_hunspell<uint32_t> ToLowerCase(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<uint32_t> t_aChar);
|
|
||||||
static tainted_hunspell<struct cs_info*> GetCurrentCS(
|
|
||||||
rlbox_sandbox_hunspell& aSandbox, tainted_hunspell<const char*> 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<uint32_t, std::unique_ptr<mozHunspellFileMgrHost>>
|
|
||||||
sFileMgrMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sFileMgrAllowList contains the filenames of the dictionary files hunspell
|
|
||||||
* is allowed to open
|
|
||||||
*/
|
|
||||||
static std::set<nsCString> 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<uint32_t> t_aFd);
|
|
||||||
};
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -154,7 +154,7 @@ diff --git a/extensions/spellcheck/hunspell/src/filemgr.hxx b/extensions/spellch
|
||||||
- private:
|
- private:
|
||||||
- FileMgr(const FileMgr&);
|
- FileMgr(const FileMgr&);
|
||||||
- FileMgr& operator=(const FileMgr&);
|
- FileMgr& operator=(const FileMgr&);
|
||||||
+#include "mozHunspellRLBoxSandbox.h"
|
+#include "mozHunspellFileMgrSandbox.h"
|
||||||
|
|
||||||
- protected:
|
- protected:
|
||||||
- std::ifstream fin;
|
- std::ifstream fin;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZILLA_CLIENT
|
#ifdef MOZILLA_CLIENT
|
||||||
#include "mozHunspellRLBoxGlue.h"
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsUnicharUtils.h"
|
||||||
|
#include "mozilla/Encoding.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct unicode_info2 {
|
struct unicode_info2 {
|
||||||
|
|
@ -2278,8 +2282,91 @@ struct cs_info* get_current_cs(const std::string& es) {
|
||||||
return ccs;
|
return ccs;
|
||||||
}
|
}
|
||||||
#else
|
#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) {
|
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
|
#endif
|
||||||
|
|
||||||
|
|
@ -2373,7 +2460,7 @@ unsigned short unicodetoupper(unsigned short c, int langnum) {
|
||||||
return static_cast<unsigned short>(u_toupper(c));
|
return static_cast<unsigned short>(u_toupper(c));
|
||||||
#else
|
#else
|
||||||
#ifdef MOZILLA_CLIENT
|
#ifdef MOZILLA_CLIENT
|
||||||
return moz_hunspell_ToUpperCase((char16_t)c);
|
return ToUpperCase((char16_t)c);
|
||||||
#else
|
#else
|
||||||
return (utf_tbl) ? utf_tbl[c].cupper : c;
|
return (utf_tbl) ? utf_tbl[c].cupper : c;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -2390,7 +2477,7 @@ unsigned short unicodetolower(unsigned short c, int langnum) {
|
||||||
return static_cast<unsigned short>(u_tolower(c));
|
return static_cast<unsigned short>(u_tolower(c));
|
||||||
#else
|
#else
|
||||||
#ifdef MOZILLA_CLIENT
|
#ifdef MOZILLA_CLIENT
|
||||||
return moz_hunspell_ToLowerCase((char16_t)c);
|
return ToLowerCase((char16_t)c);
|
||||||
#else
|
#else
|
||||||
return (utf_tbl) ? utf_tbl[c].clower : c;
|
return (utf_tbl) ? utf_tbl[c].clower : c;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,10 @@
|
||||||
#include "w_char.hxx"
|
#include "w_char.hxx"
|
||||||
#include "htypes.hxx"
|
#include "htypes.hxx"
|
||||||
|
|
||||||
|
#ifdef MOZILLA_CLIENT
|
||||||
|
#include "nscore.h" // for mozalloc headers
|
||||||
|
#endif
|
||||||
|
|
||||||
// casing
|
// casing
|
||||||
#define NOCAP 0
|
#define NOCAP 0
|
||||||
#define INITCAP 1
|
#define INITCAP 1
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,6 @@
|
||||||
#ifndef FILEMGR_HXX_
|
#ifndef FILEMGR_HXX_
|
||||||
#define FILEMGR_HXX_
|
#define FILEMGR_HXX_
|
||||||
|
|
||||||
#include "mozHunspellRLBoxSandbox.h"
|
#include "mozHunspellFileMgrSandbox.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# 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/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
all_sources = [
|
UNIFIED_SOURCES += [
|
||||||
'../glue/mozHunspellRLBoxSandbox.cpp',
|
'../glue/mozHunspellFileMgrSandbox.cpp',
|
||||||
'affentry.cxx',
|
'affentry.cxx',
|
||||||
'affixmgr.cxx',
|
'affixmgr.cxx',
|
||||||
'csutil.cxx',
|
'csutil.cxx',
|
||||||
|
|
@ -16,13 +16,6 @@ all_sources = [
|
||||||
'suggestmgr.cxx',
|
'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
|
DEFINES['HUNSPELL_STATIC'] = True
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,6 @@ nsAutoCString GetSandboxedOggPath() {
|
||||||
nsLiteralCString(MOZ_DLL_PREFIX "oggwasm" MOZ_DLL_SUFFIX));
|
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) {
|
PRLibrary* PreloadLibrary(const nsAutoCString& path) {
|
||||||
PRLibSpec libSpec;
|
PRLibSpec libSpec;
|
||||||
libSpec.type = PR_LibSpec_Pathname;
|
libSpec.type = PR_LibSpec_Pathname;
|
||||||
|
|
@ -80,11 +75,6 @@ void PreloadSandboxedDynamicLibraries() {
|
||||||
MOZ_CRASH("Library preload failure: Failed to load libogg\n");
|
MOZ_CRASH("Library preload failure: Failed to load libogg\n");
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
# if defined(MOZ_WASM_SANDBOXING_HUNSPELL)
|
|
||||||
if (!PreloadLibrary(GetSandboxedHunspellPath())) {
|
|
||||||
MOZ_CRASH("Library preload failure: Failed to load libhunspell\n");
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ namespace mozilla {
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
nsAutoCString GetSandboxedGraphitePath();
|
nsAutoCString GetSandboxedGraphitePath();
|
||||||
nsAutoCString GetSandboxedOggPath();
|
nsAutoCString GetSandboxedOggPath();
|
||||||
nsAutoCString GetSandboxedHunspellPath();
|
|
||||||
void PreloadSandboxedDynamicLibraries();
|
void PreloadSandboxedDynamicLibraries();
|
||||||
} // namespace ipc
|
} // namespace ipc
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
|
|
@ -2045,7 +2045,6 @@ def wasm_sandboxing_libraries():
|
||||||
return (
|
return (
|
||||||
"graphite",
|
"graphite",
|
||||||
"ogg",
|
"ogg",
|
||||||
"hunspell",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue