mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 05:10:49 +00:00
Bug 1657573: Change libhunspell's file access code to use function pointers r=froydnj
Differential Revision: https://phabricator.services.mozilla.com/D86173
This commit is contained in:
parent
f4905cc23b
commit
571754630f
@ -6,7 +6,7 @@
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'mozHunspell.cpp',
|
||||
'mozHunspellFileMgr.cpp',
|
||||
'mozHunspellFileMgrHost.cpp',
|
||||
'RemoteSpellCheckEngineChild.cpp',
|
||||
'RemoteSpellCheckEngineParent.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"
|
||||
@ -183,6 +185,9 @@ mozHunspell::SetDictionary(const nsAString& aDictionary) {
|
||||
mDictionary = aDictionary;
|
||||
mAffixFileName = affFileName;
|
||||
|
||||
RegisterHunspellCallbacks(
|
||||
mozHunspellCallbacks::CreateFilemgr, mozHunspellCallbacks::GetLine,
|
||||
mozHunspellCallbacks::GetLineNum, mozHunspellCallbacks::DestructFilemgr);
|
||||
mHunspell = new Hunspell(affFileName.get(), dictFileName.get());
|
||||
if (!mHunspell) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -1,59 +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 "mozHunspellFileMgr.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
FileMgr::FileMgr(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> FileMgr::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> FileMgr::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 FileMgr::getline(std::string& aResult) {
|
||||
nsAutoCString line;
|
||||
auto res = ReadLine(line);
|
||||
if (res.isErr()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aResult.assign(line.BeginReading(), line.Length());
|
||||
return true;
|
||||
}
|
37
extensions/spellcheck/hunspell/glue/mozHunspellFileMgrGlue.h
Normal file
37
extensions/spellcheck/hunspell/glue/mozHunspellFileMgrGlue.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*- 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 mozHunspellFileMgrGlue_h
|
||||
#define mozHunspellFileMgrGlue_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
void RegisterHunspellCallbacks(
|
||||
hunspell_create_filemgr_t* aHunspellCreateFilemgr,
|
||||
hunspell_get_line_t* aHunspellGetLine,
|
||||
hunspell_get_line_num_t* aHunspellGetLine_num,
|
||||
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;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
138
extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.cpp
Normal file
138
extensions/spellcheck/hunspell/glue/mozHunspellFileMgrHost.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
/* -*- 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 "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
|
@ -0,0 +1,44 @@
|
||||
/* -*- 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 "mozHunspellFileMgrSandbox.h"
|
||||
#include "mozHunspellFileMgrGlue.h"
|
||||
|
||||
FileMgr::FileMgr(const char* aFilename, const char* aKey) : mFd(0) {
|
||||
mFd = moz_glue_hunspell_create_filemgr(aFilename, aKey);
|
||||
}
|
||||
|
||||
bool FileMgr::getline(std::string& aResult) {
|
||||
char* line = nullptr;
|
||||
bool ok = moz_glue_hunspell_get_line(mFd, &line);
|
||||
if (ok && line) {
|
||||
aResult = line;
|
||||
free(line);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
int FileMgr::getlinenum() const { return moz_glue_hunspell_get_line_num(mFd); }
|
||||
|
||||
FileMgr::~FileMgr() { moz_glue_hunspell_destruct_filemgr(mFd); }
|
||||
|
||||
// Glue code to set global callbacks
|
||||
|
||||
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;
|
||||
|
||||
void RegisterHunspellCallbacks(
|
||||
hunspell_create_filemgr_t* aHunspellCreateFilemgr,
|
||||
hunspell_get_line_t* aHunspellGetLine,
|
||||
hunspell_get_line_num_t* aHunspellGetLine_num,
|
||||
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;
|
||||
}
|
@ -4,10 +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/. */
|
||||
|
||||
#ifndef mozHunspellFileMgr_h
|
||||
#define mozHunspellFileMgr_h
|
||||
#ifndef mozHunspellFileMgrSandbox_h
|
||||
#define mozHunspellFileMgrSandbox_h
|
||||
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
@ -25,21 +26,16 @@ class FileMgr final {
|
||||
* unsupported. The argument is there solely for compatibility.
|
||||
*/
|
||||
explicit FileMgr(const char* aFilename, const char* aKey = nullptr);
|
||||
~FileMgr() = default;
|
||||
~FileMgr();
|
||||
|
||||
// Note: The nonstandard naming conventions of these methods are necessary for
|
||||
// Hunspell compatibility.
|
||||
bool getline(std::string& aLine);
|
||||
int getlinenum() const { return mLineNum; }
|
||||
int getlinenum() const;
|
||||
|
||||
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;
|
||||
// opaque file descriptor got from the host application
|
||||
uint32_t mFd;
|
||||
};
|
||||
|
||||
#endif // mozHunspellFileMgr_h
|
||||
#endif // mozHunspellFileMgrSandbox_h
|
@ -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 "mozHunspellFileMgr.h"
|
||||
+#include "mozHunspellFileMgrSandbox.h"
|
||||
|
||||
- protected:
|
||||
- std::ifstream fin;
|
||||
|
@ -72,6 +72,6 @@
|
||||
#ifndef FILEMGR_HXX_
|
||||
#define FILEMGR_HXX_
|
||||
|
||||
#include "mozHunspellFileMgr.h"
|
||||
#include "mozHunspellFileMgrSandbox.h"
|
||||
|
||||
#endif
|
||||
|
@ -5,6 +5,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'../glue/mozHunspellFileMgrSandbox.cpp',
|
||||
'affentry.cxx',
|
||||
'affixmgr.cxx',
|
||||
'csutil.cxx',
|
||||
|
Loading…
x
Reference in New Issue
Block a user