mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1646543 - Replace blacklist with more appropriate names. r=xpcom-reviewers,nika
This removes variants of "blacklist" from the xpcom directory. The preference name "network.file.path_blacklist" is left in place and will need a more thorough plan for removal. Instances of `MOZ_ASAN_BLACKLIST` remain as well and should be replaced in a larger modifcation of the `#define` in the mfbt component. Differential Revision: https://phabricator.services.mozilla.com/D80098
This commit is contained in:
parent
0f92ede9c2
commit
ba9b93f039
@ -887,7 +887,7 @@ with modules["DOM_XPATH"]:
|
||||
with modules["URILOADER"]:
|
||||
errors["NS_ERROR_WONT_HANDLE_CONTENT"] = FAILURE(1)
|
||||
# The load has been cancelled because it was found on a malware or phishing
|
||||
# blacklist.
|
||||
# list.
|
||||
errors["NS_ERROR_MALWARE_URI"] = FAILURE(30)
|
||||
errors["NS_ERROR_PHISHING_URI"] = FAILURE(31)
|
||||
errors["NS_ERROR_TRACKING_URI"] = FAILURE(34)
|
||||
|
@ -40,16 +40,15 @@ Interface members const/method/attribute conform to the following pattern:
|
||||
|
||||
|
||||
# XXX(nika): Fix the IDL files which do this so we can remove this list?
|
||||
def rustBlacklistedForward(s):
|
||||
def rustPreventForward(s):
|
||||
"""These types are foward declared as interfaces, but never actually defined
|
||||
in IDL files. We don't want to generate references to them in rust for that
|
||||
reason."""
|
||||
blacklisted = [
|
||||
return s in (
|
||||
"nsIFrame",
|
||||
"nsIObjectFrame",
|
||||
"nsSubDocumentFrame",
|
||||
]
|
||||
return s in blacklisted
|
||||
)
|
||||
|
||||
|
||||
def attlistToIDL(attlist):
|
||||
@ -465,7 +464,7 @@ class Forward(object):
|
||||
return "%s *%s" % (self.name, '*' if 'out' in calltype else '')
|
||||
|
||||
def rustType(self, calltype):
|
||||
if rustBlacklistedForward(self.name):
|
||||
if rustPreventForward(self.name):
|
||||
raise RustNoncompat("forward declaration %s is unsupported" % self.name)
|
||||
if calltype == 'element':
|
||||
return 'RefPtr<%s>' % self.name
|
||||
|
@ -44,19 +44,19 @@ typedef char char_path_t;
|
||||
// Initially false to make concurrent consumers acquire the lock and sync.
|
||||
// The plain bool is synchronized with sMutex, the atomic one is for a quick
|
||||
// check w/o the need to acquire the lock on the hot path.
|
||||
static bool sBlacklistEmpty = false;
|
||||
static Atomic<bool, Relaxed> sBlacklistEmptyQuickCheck{false};
|
||||
static bool sForbiddenPathsEmpty = false;
|
||||
static Atomic<bool, Relaxed> sForbiddenPathsEmptyQuickCheck{false};
|
||||
|
||||
typedef nsTArray<nsTString<char_path_t>> Paths;
|
||||
static StaticAutoPtr<Paths> sBlacklist;
|
||||
static StaticAutoPtr<Paths> sForbiddenPaths;
|
||||
|
||||
static Paths& PathBlacklist() {
|
||||
static Paths& ForbiddenPaths() {
|
||||
sMutex.AssertCurrentThreadOwns();
|
||||
if (!sBlacklist) {
|
||||
sBlacklist = new nsTArray<nsTString<char_path_t>>();
|
||||
ClearOnShutdown(&sBlacklist);
|
||||
if (!sForbiddenPaths) {
|
||||
sForbiddenPaths = new nsTArray<nsTString<char_path_t>>();
|
||||
ClearOnShutdown(&sForbiddenPaths);
|
||||
}
|
||||
return *sBlacklist;
|
||||
return *sForbiddenPaths;
|
||||
}
|
||||
|
||||
static void AllowUNCDirectory(char const* directory) {
|
||||
@ -89,33 +89,34 @@ void InitPrefs() {
|
||||
sBlockUNCPaths =
|
||||
Preferences::GetBool("network.file.disable_unc_paths", false);
|
||||
|
||||
nsTAutoString<char_path_t> blacklist;
|
||||
nsTAutoString<char_path_t> forbidden;
|
||||
#ifdef XP_WIN
|
||||
Preferences::GetString("network.file.path_blacklist", blacklist);
|
||||
Preferences::GetString("network.file.path_blacklist", forbidden);
|
||||
#else
|
||||
Preferences::GetCString("network.file.path_blacklist", blacklist);
|
||||
Preferences::GetCString("network.file.path_blacklist", forbidden);
|
||||
#endif
|
||||
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
|
||||
if (blacklist.IsEmpty()) {
|
||||
sBlacklistEmptyQuickCheck = (sBlacklistEmpty = true);
|
||||
if (forbidden.IsEmpty()) {
|
||||
sForbiddenPathsEmptyQuickCheck = (sForbiddenPathsEmpty = true);
|
||||
return;
|
||||
}
|
||||
|
||||
PathBlacklist().Clear();
|
||||
TTokenizer<char_path_t> p(blacklist);
|
||||
ForbiddenPaths().Clear();
|
||||
TTokenizer<char_path_t> p(forbidden);
|
||||
while (!p.CheckEOF()) {
|
||||
nsTString<char_path_t> path;
|
||||
Unused << p.ReadUntil(TTokenizer<char_path_t>::Token::Char(','), path);
|
||||
path.Trim(" ");
|
||||
if (!path.IsEmpty()) {
|
||||
PathBlacklist().AppendElement(path);
|
||||
ForbiddenPaths().AppendElement(path);
|
||||
}
|
||||
Unused << p.CheckChar(',');
|
||||
}
|
||||
|
||||
sBlacklistEmptyQuickCheck = (sBlacklistEmpty = PathBlacklist().Length() == 0);
|
||||
sForbiddenPathsEmptyQuickCheck =
|
||||
(sForbiddenPathsEmpty = ForbiddenPaths().Length() == 0);
|
||||
}
|
||||
|
||||
void InitDirectoriesWhitelist() {
|
||||
@ -307,19 +308,19 @@ bool IsAllowedPath(const nsTSubstring<char_path_t>& aFilePath) {
|
||||
typedef TNormalizer<char_path_t> Normalizer;
|
||||
|
||||
// An atomic quick check out of the lock, because this is mostly `true`.
|
||||
if (sBlacklistEmptyQuickCheck) {
|
||||
if (sForbiddenPathsEmptyQuickCheck) {
|
||||
return true;
|
||||
}
|
||||
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
|
||||
if (sBlacklistEmpty) {
|
||||
if (sForbiddenPathsEmpty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If sBlacklist has been cleared at shutdown, we must avoid calling
|
||||
// PathBlacklist() again, as that will recreate the array and we will leak.
|
||||
if (!sBlacklist) {
|
||||
// If sForbidden has been cleared at shutdown, we must avoid calling
|
||||
// ForbiddenPaths() again, as that will recreate the array and we will leak.
|
||||
if (!sForbiddenPaths) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -330,7 +331,7 @@ bool IsAllowedPath(const nsTSubstring<char_path_t>& aFilePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& prefix : PathBlacklist()) {
|
||||
for (const auto& prefix : ForbiddenPaths()) {
|
||||
if (StringBeginsWith(normalized, prefix)) {
|
||||
if (normalized.Length() > prefix.Length() &&
|
||||
normalized[prefix.Length()] != kPathSeparator) {
|
||||
|
@ -10,11 +10,13 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
const char kForbiddenPathsPref[] = "network.file.path_blacklist";
|
||||
|
||||
TEST(TestFilePreferencesUnix, Parsing)
|
||||
{
|
||||
#define kBlacklisted "/tmp/blacklisted"
|
||||
#define kBlacklistedDir "/tmp/blacklisted/"
|
||||
#define kBlacklistedFile "/tmp/blacklisted/file"
|
||||
#define kForbidden "/tmp/forbidden"
|
||||
#define kForbiddenDir "/tmp/forbidden/"
|
||||
#define kForbiddenFile "/tmp/forbidden/file"
|
||||
#define kOther "/tmp/other"
|
||||
#define kOtherDir "/tmp/other/"
|
||||
#define kOtherFile "/tmp/other/file"
|
||||
@ -23,16 +25,15 @@ TEST(TestFilePreferencesUnix, Parsing)
|
||||
// This is run on exit of this function to make sure we clear the pref
|
||||
// and that behaviour with the pref cleared is correct.
|
||||
auto cleanup = MakeScopeExit([&] {
|
||||
nsresult rv = Preferences::ClearUser("network.file.path_blacklist");
|
||||
nsresult rv = Preferences::ClearUser(kForbiddenPathsPref);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
FilePreferences::InitPrefs();
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklisted)),
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kForbidden)),
|
||||
true);
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kForbiddenDir)),
|
||||
true);
|
||||
ASSERT_EQ(
|
||||
FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedDir)),
|
||||
true);
|
||||
ASSERT_EQ(
|
||||
FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedFile)),
|
||||
FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kForbiddenFile)),
|
||||
true);
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kAllowed)),
|
||||
true);
|
||||
@ -40,29 +41,27 @@ TEST(TestFilePreferencesUnix, Parsing)
|
||||
|
||||
auto CheckPrefs = [](const nsACString& aPaths) {
|
||||
nsresult rv;
|
||||
rv = Preferences::SetCString("network.file.path_blacklist", aPaths);
|
||||
rv = Preferences::SetCString(kForbiddenPathsPref, aPaths);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
FilePreferences::InitPrefs();
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kForbiddenDir)),
|
||||
false);
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kForbiddenDir)),
|
||||
false);
|
||||
ASSERT_EQ(
|
||||
FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedDir)),
|
||||
FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kForbiddenFile)),
|
||||
false);
|
||||
ASSERT_EQ(
|
||||
FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedDir)),
|
||||
false);
|
||||
ASSERT_EQ(
|
||||
FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklistedFile)),
|
||||
false);
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kBlacklisted)),
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kForbidden)),
|
||||
false);
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kAllowed)),
|
||||
true);
|
||||
};
|
||||
|
||||
CheckPrefs(NS_LITERAL_CSTRING(kBlacklisted));
|
||||
CheckPrefs(NS_LITERAL_CSTRING(kBlacklisted "," kOther));
|
||||
CheckPrefs(NS_LITERAL_CSTRING(kForbidden));
|
||||
CheckPrefs(NS_LITERAL_CSTRING(kForbidden "," kOther));
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kOtherFile)),
|
||||
false);
|
||||
CheckPrefs(NS_LITERAL_CSTRING(kBlacklisted "," kOther ","));
|
||||
CheckPrefs(NS_LITERAL_CSTRING(kForbidden "," kOther ","));
|
||||
ASSERT_EQ(FilePreferences::IsAllowedPath(NS_LITERAL_CSTRING(kOtherFile)),
|
||||
false);
|
||||
}
|
||||
@ -71,62 +70,62 @@ TEST(TestFilePreferencesUnix, Simple)
|
||||
{
|
||||
nsAutoCString tempPath;
|
||||
|
||||
// This is the directory we will blacklist
|
||||
nsCOMPtr<nsIFile> blacklistedDir;
|
||||
// This is the directory we will forbid
|
||||
nsCOMPtr<nsIFile> forbiddenDir;
|
||||
nsresult rv =
|
||||
NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(blacklistedDir));
|
||||
NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(forbiddenDir));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = blacklistedDir->GetNativePath(tempPath);
|
||||
rv = forbiddenDir->GetNativePath(tempPath);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = blacklistedDir->AppendNative(NS_LITERAL_CSTRING("blacklisted_dir"));
|
||||
rv = forbiddenDir->AppendNative(NS_LITERAL_CSTRING("forbidden_dir"));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
|
||||
// This is executed at exit to clean up after ourselves.
|
||||
auto cleanup = MakeScopeExit([&] {
|
||||
nsresult rv = Preferences::ClearUser("network.file.path_blacklist");
|
||||
nsresult rv = Preferences::ClearUser(kForbiddenPathsPref);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
FilePreferences::InitPrefs();
|
||||
|
||||
rv = blacklistedDir->Remove(true);
|
||||
rv = forbiddenDir->Remove(true);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
});
|
||||
|
||||
// Create the directory
|
||||
rv = blacklistedDir->Create(nsIFile::DIRECTORY_TYPE, 0666);
|
||||
rv = forbiddenDir->Create(nsIFile::DIRECTORY_TYPE, 0666);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
|
||||
// This is the file we will try to access
|
||||
nsCOMPtr<nsIFile> blacklistedFile;
|
||||
rv = blacklistedDir->Clone(getter_AddRefs(blacklistedFile));
|
||||
nsCOMPtr<nsIFile> forbiddenFile;
|
||||
rv = forbiddenDir->Clone(getter_AddRefs(forbiddenFile));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = blacklistedFile->AppendNative(NS_LITERAL_CSTRING("test_file"));
|
||||
rv = forbiddenFile->AppendNative(NS_LITERAL_CSTRING("test_file"));
|
||||
|
||||
// Create the file
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = blacklistedFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
|
||||
rv = forbiddenFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
|
||||
|
||||
// Get the path for the blacklist
|
||||
nsAutoCString blackListPath;
|
||||
rv = blacklistedDir->GetNativePath(blackListPath);
|
||||
// Get the forbidden path
|
||||
nsAutoCString forbiddenPath;
|
||||
rv = forbiddenDir->GetNativePath(forbiddenPath);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
|
||||
// Set the pref and make sure it is enforced
|
||||
rv = Preferences::SetCString("network.file.path_blacklist", blackListPath);
|
||||
rv = Preferences::SetCString(kForbiddenPathsPref, forbiddenPath);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
FilePreferences::InitPrefs();
|
||||
|
||||
// Check that we can't access some of the file attributes
|
||||
int64_t size;
|
||||
rv = blacklistedFile->GetFileSize(&size);
|
||||
rv = forbiddenFile->GetFileSize(&size);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
bool exists;
|
||||
rv = blacklistedFile->Exists(&exists);
|
||||
rv = forbiddenFile->Exists(&exists);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
// Check that we can't enumerate the directory
|
||||
nsCOMPtr<nsIDirectoryEnumerator> dirEnumerator;
|
||||
rv = blacklistedDir->GetDirectoryEntries(getter_AddRefs(dirEnumerator));
|
||||
rv = forbiddenDir->GetDirectoryEntries(getter_AddRefs(dirEnumerator));
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
nsCOMPtr<nsIFile> newPath;
|
||||
@ -134,7 +133,7 @@ TEST(TestFilePreferencesUnix, Simple)
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->AppendNative(NS_LITERAL_CSTRING("."));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->AppendNative(NS_LITERAL_CSTRING("blacklisted_dir"));
|
||||
rv = newPath->AppendNative(NS_LITERAL_CSTRING("forbidden_dir"));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->Exists(&exists);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
@ -148,7 +147,7 @@ TEST(TestFilePreferencesUnix, Simple)
|
||||
rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(newPath));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->AppendRelativeNativePath(
|
||||
NS_LITERAL_CSTRING("./blacklisted_dir/file"));
|
||||
NS_LITERAL_CSTRING("./forbidden_dir/file"));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->Exists(&exists);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
@ -157,7 +156,7 @@ TEST(TestFilePreferencesUnix, Simple)
|
||||
rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(newPath));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->AppendRelativeNativePath(
|
||||
NS_LITERAL_CSTRING("allowed/../blacklisted_dir/file"));
|
||||
NS_LITERAL_CSTRING("allowed/../forbidden_dir/file"));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->Exists(&exists);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
@ -168,54 +167,54 @@ TEST(TestFilePreferencesUnix, Simple)
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->AppendNative(NS_LITERAL_CSTRING(".."));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->AppendNative(NS_LITERAL_CSTRING("blacklisted_dir"));
|
||||
rv = newPath->AppendNative(NS_LITERAL_CSTRING("forbidden_dir"));
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
rv = newPath->Exists(&exists);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
nsAutoCString trickyPath(tempPath);
|
||||
trickyPath.AppendLiteral("/allowed/../blacklisted_dir/file");
|
||||
trickyPath.AppendLiteral("/allowed/../forbidden_dir/file");
|
||||
rv = newPath->InitWithNativePath(trickyPath);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
// Check that we can't construct a path that is functionally the same
|
||||
// as the blacklisted one and bypasses the filter.
|
||||
// as the forbidden one and bypasses the filter.
|
||||
trickyPath = tempPath;
|
||||
trickyPath.AppendLiteral("/./blacklisted_dir/file");
|
||||
trickyPath.AppendLiteral("/./forbidden_dir/file");
|
||||
rv = newPath->InitWithNativePath(trickyPath);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
trickyPath = tempPath;
|
||||
trickyPath.AppendLiteral("//blacklisted_dir/file");
|
||||
trickyPath.AppendLiteral("//forbidden_dir/file");
|
||||
rv = newPath->InitWithNativePath(trickyPath);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
trickyPath.Truncate();
|
||||
trickyPath.AppendLiteral("//");
|
||||
trickyPath.Append(tempPath);
|
||||
trickyPath.AppendLiteral("/blacklisted_dir/file");
|
||||
trickyPath.AppendLiteral("/forbidden_dir/file");
|
||||
rv = newPath->InitWithNativePath(trickyPath);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
trickyPath.Truncate();
|
||||
trickyPath.AppendLiteral("//");
|
||||
trickyPath.Append(tempPath);
|
||||
trickyPath.AppendLiteral("//blacklisted_dir/file");
|
||||
trickyPath.AppendLiteral("//forbidden_dir/file");
|
||||
rv = newPath->InitWithNativePath(trickyPath);
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
|
||||
// Check that if the blacklisted string is a directory, we only block access
|
||||
// Check that if the forbidden string is a directory, we only block access
|
||||
// to subresources, not the directory itself.
|
||||
nsAutoCString blacklistDirPath(blackListPath);
|
||||
blacklistDirPath.Append("/");
|
||||
rv = Preferences::SetCString("network.file.path_blacklist", blacklistDirPath);
|
||||
nsAutoCString forbiddenDirPath(forbiddenPath);
|
||||
forbiddenDirPath.Append("/");
|
||||
rv = Preferences::SetCString(kForbiddenPathsPref, forbiddenDirPath);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
FilePreferences::InitPrefs();
|
||||
|
||||
// This should work, since we only block subresources
|
||||
rv = blacklistedDir->Exists(&exists);
|
||||
rv = forbiddenDir->Exists(&exists);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
|
||||
rv = blacklistedDir->GetDirectoryEntries(getter_AddRefs(dirEnumerator));
|
||||
rv = forbiddenDir->GetDirectoryEntries(getter_AddRefs(dirEnumerator));
|
||||
ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
}
|
||||
|
@ -772,7 +772,7 @@ class nsRunnableMethod
|
||||
|
||||
virtual void Revoke() = 0;
|
||||
|
||||
// These ReturnTypeEnforcer classes set up a blacklist for return types that
|
||||
// These ReturnTypeEnforcer classes disallow return types that
|
||||
// we know are not safe. The default ReturnTypeEnforcer compiles just fine but
|
||||
// already_AddRefed will not.
|
||||
template <typename OtherReturnType>
|
||||
|
Loading…
Reference in New Issue
Block a user