Bug 1793463 - Part 4: Generate static components entries for protocols, r=necko-reviewers,xpcom-reviewers,valentin,kmag

This adds a new set of options to static components.conf files to allow
specifying the protocol flags and default ports of a protocol handler, and
generates a separate table just for this purpose.

This will be used in the next part as part of replacing the existing protocol
handler lookup infrastructure.

Differential Revision: https://phabricator.services.mozilla.com/D162803
This commit is contained in:
Nika Layzell 2022-11-30 18:13:42 +00:00
Родитель 6c329ad26c
Коммит 90f7562d95
15 изменённых файлов: 355 добавлений и 0 удалений

Просмотреть файл

@ -84,10 +84,22 @@ Classes = [
'headers': ['/docshell/base/nsAboutRedirector.h'],
},
{
'name': 'ExternalProtocolHandler',
'cid': '{bd6390c8-fbea-11d4-98f6-001083010e9b}',
'contract_ids': ['@mozilla.org/network/protocol;1?name=default'],
'type': 'nsExternalProtocolHandler',
'headers': ['/uriloader/exthandler/nsExternalProtocolHandler.h'],
'protocol_config': {
'scheme': 'default',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_LOADABLE_BY_ANYONE',
'URI_NON_PERSISTABLE',
'URI_DOES_NOT_RETURN_DATA',
],
'default_port': 0,
},
'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
},
{

Просмотреть файл

@ -10,11 +10,31 @@ Classes = [
'contract_ids': ['@mozilla.org/network/protocol;1?name=moz-fonttable'],
'type': 'mozilla::dom::FontTableURIProtocolHandler',
'headers': ['mozilla/dom/FontTableURIProtocolHandler.h'],
'protocol_config': {
'scheme': 'moz-fonttable',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_LOADABLE_BY_SUBSUMERS',
'URI_NON_PERSISTABLE',
'URI_IS_LOCAL_RESOURCE',
],
},
},
{
'cid': '{b43964aa-a078-44b2-b06b-fd4d1b172e66}',
'contract_ids': ['@mozilla.org/network/protocol;1?name=blob'],
'type': 'mozilla::dom::BlobURLProtocolHandler',
'headers': ['mozilla/dom/BlobURLProtocolHandler.h'],
'protocol_config': {
'scheme': 'blob',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_LOADABLE_BY_SUBSUMERS',
'URI_NON_PERSISTABLE',
'URI_IS_LOCAL_RESOURCE',
],
},
},
]

Просмотреть файл

@ -10,5 +10,14 @@ Classes = [
'contract_ids': ['@mozilla.org/network/protocol;1?name=indexeddb'],
'type': 'nsIndexedDBProtocolHandler',
'headers': ['/dom/quota/nsIndexedDBProtocolHandler.h'],
'protocol_config': {
'scheme': 'indexeddb',
'flags': [
'URI_STD',
'URI_DANGEROUS_TO_LOAD',
'URI_DOES_NOT_RETURN_DATA',
'URI_NON_PERSISTABLE',
],
},
},
]

Просмотреть файл

@ -10,6 +10,16 @@ Classes = [
'contract_ids': ['@mozilla.org/network/protocol;1?name=moz-icon'],
'type': 'nsIconProtocolHandler',
'headers': ['/image/decoders/icon/nsIconProtocolHandler.h'],
'protocol_config': {
'scheme': 'moz-icon',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_IS_UI_RESOURCE',
'URI_IS_LOCAL_RESOURCE',
],
'default_port': 0,
},
},
{
'cid': '{1460df3b-774c-4205-8349-838e507c3ef9}',

Просмотреть файл

@ -322,6 +322,17 @@ Classes = [
'contract_ids': ['@mozilla.org/network/protocol;1?name=javascript'],
'type': 'nsJSProtocolHandler',
'headers': ['nsJSProtocolHandler.h'],
'protocol_config': {
'scheme': 'javascript',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_INHERITS_SECURITY_CONTEXT',
'URI_LOADABLE_BY_ANYONE',
'URI_NON_PERSISTABLE',
'URI_OPENING_EXECUTES_SCRIPT',
],
},
},
{
'cid': '{ac9e3e82-bfbd-4f26-941e-f58c8ee178c1}',

Просмотреть файл

@ -18,6 +18,16 @@ Classes = [
'type': 'nsJARProtocolHandler',
'headers': ['/modules/libjar/nsJARProtocolHandler.h'],
'constructor': 'nsJARProtocolHandler::GetSingleton',
'protocol_config': {
'scheme': 'jar',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
# URI_LOADABLE_BY_ANYONE, since it's our inner URI that will
# matter anyway.
'URI_LOADABLE_BY_ANYONE',
],
},
},
{
'cid': '{245abae2-b947-4ded-a46d-9829d3cca462}',

Просмотреть файл

@ -290,6 +290,16 @@ Classes = [
'singleton': True,
'type': 'mozilla::net::nsAboutProtocolHandler',
'headers': ['/netwerk/protocol/about/nsAboutProtocolHandler.h'],
'protocol_config': {
'scheme': 'about',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_DANGEROUS_TO_LOAD',
'URI_SCHEME_NOT_SELF_LINKABLE',
],
'has_dynamic_flags': True,
},
},
{
'cid': '{b6ed3030-6183-11d3-a178-0050041caf44}',
@ -297,6 +307,18 @@ Classes = [
'singleton': True,
'legacy_constructor': 'nsDataHandler::Create',
'headers': ['/netwerk/protocol/data/nsDataHandler.h'],
'protocol_config': {
'scheme': 'data',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_INHERITS_SECURITY_CONTEXT',
'URI_LOADABLE_BY_ANYONE',
'URI_NON_PERSISTABLE',
'URI_IS_LOCAL_RESOURCE',
'URI_SYNC_LOAD_IS_OK',
],
},
},
{
'cid': '{fbc81170-1f69-11d3-9344-00104ba0fd40}',
@ -305,6 +327,15 @@ Classes = [
'type': 'nsFileProtocolHandler',
'headers': ['mozilla/net/nsFileProtocolHandler.h'],
'init_method': 'Init',
'protocol_config': {
'scheme': 'file',
'flags': [
'URI_NOAUTH',
'URI_IS_LOCAL_FILE',
'URI_IS_LOCAL_RESOURCE',
'URI_IS_POTENTIALLY_TRUSTWORTHY',
],
},
},
{
'cid': '{4f47e42e-4d23-4dd3-bfda-eb29255e9ea3}',
@ -312,6 +343,16 @@ Classes = [
'singleton': True,
'type': 'mozilla::net::nsHttpHandler',
'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
'protocol_config': {
'scheme': 'http',
'flags': [
'URI_STD',
'ALLOWS_PROXY',
'ALLOWS_PROXY_HTTP',
'URI_LOADABLE_BY_ANYONE',
],
'default_port': 80,
},
},
{
'cid': '{dccbe7e4-7750-466b-a557-5ea36c8ff24e}',
@ -319,6 +360,17 @@ Classes = [
'singleton': True,
'type': 'mozilla::net::nsHttpsHandler',
'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
'protocol_config': {
'scheme': 'https',
'flags': [
'URI_STD',
'ALLOWS_PROXY',
'ALLOWS_PROXY_HTTP',
'URI_LOADABLE_BY_ANYONE',
'URI_IS_POTENTIALLY_TRUSTWORTHY',
],
'default_port': 443,
},
},
{
'cid': '{aea16cd0-f020-4138-b068-0716c4a15b5a}',
@ -327,6 +379,15 @@ Classes = [
'type': 'mozilla::net::ExtensionProtocolHandler',
'headers': ['mozilla/net/ExtensionProtocolHandler.h'],
'constructor': 'mozilla::net::ExtensionProtocolHandler::GetSingleton',
'protocol_config': {
'scheme': 'moz-extension',
'flags': [
'URI_STD',
'URI_IS_LOCAL_RESOURCE',
'URI_IS_POTENTIALLY_TRUSTWORTHY',
],
'has_dynamic_flags': True,
},
},
{
'cid': '{450a2b55-620a-44b3-9f67-839b3b0c329c}',
@ -335,6 +396,16 @@ Classes = [
'type': 'mozilla::net::PageThumbProtocolHandler',
'headers': ['mozilla/net/PageThumbProtocolHandler.h'],
'constructor': 'mozilla::net::PageThumbProtocolHandler::GetSingleton',
'protocol_config': {
'scheme': 'moz-page-thumb',
'flags': [
'URI_STD',
'URI_IS_UI_RESOURCE',
'URI_IS_LOCAL_RESOURCE',
'URI_NORELATIVE',
'URI_NOAUTH',
],
},
},
{
'cid': '{1423e739-782c-4081-b5d8-fe6fba68c0ef}',
@ -342,6 +413,15 @@ Classes = [
'singleton': True,
'type': 'mozilla::net::nsSafeAboutProtocolHandler',
'headers': ['/netwerk/protocol/about/nsAboutProtocolHandler.h'],
'protocol_config': {
'scheme': 'moz-safe-about',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_LOADABLE_BY_ANYONE',
'URI_IS_POTENTIALLY_TRUSTWORTHY',
],
},
},
{
'cid': '{e64f152a-9f07-11d3-8cda-0060b0fc14a3}',
@ -350,6 +430,15 @@ Classes = [
'type': 'nsResProtocolHandler',
'headers': ['/netwerk/protocol/res/nsResProtocolHandler.h'],
'constructor': 'nsResProtocolHandler::GetSingleton',
'protocol_config': {
'scheme': 'resource',
'flags': [
'URI_STD',
'URI_IS_UI_RESOURCE',
'URI_IS_LOCAL_RESOURCE',
'URI_IS_POTENTIALLY_TRUSTWORTHY',
],
},
},
{
'cid': '{9c7ec5d1-23f9-11d5-aea8-8fcc0793e97f}',
@ -357,18 +446,53 @@ Classes = [
'singleton': True,
'type': 'mozilla::net::nsViewSourceHandler',
'headers': ['/netwerk/protocol/viewsource/nsViewSourceHandler.h'],
'protocol_config': {
'scheme': 'view-source',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_DANGEROUS_TO_LOAD',
'URI_NON_PERSISTABLE',
],
'has_dynamic_flags': True,
},
},
{
'cid': '{dc01db59-a513-4c90-824b-085cce06c0aa}',
'contract_ids': ['@mozilla.org/network/protocol;1?name=ws'],
'singleton': True,
'legacy_constructor': 'mozilla::net::WebSocketChannelConstructor',
'protocol_config': {
'scheme': 'ws',
'flags': [
'URI_NORELATIVE',
'URI_NON_PERSISTABLE',
'ALLOWS_PROXY',
'ALLOWS_PROXY_HTTP',
'URI_DOES_NOT_RETURN_DATA',
'URI_DANGEROUS_TO_LOAD',
],
'default_port': 80,
},
},
{
'cid': '{dc01dbbb-a5bb-4cbb-82bb-085cce06c0bb}',
'contract_ids': ['@mozilla.org/network/protocol;1?name=wss'],
'singleton': True,
'legacy_constructor': 'mozilla::net::WebSocketSSLChannelConstructor',
'protocol_config': {
'scheme': 'wss',
'flags': [
'URI_NORELATIVE',
'URI_NON_PERSISTABLE',
'ALLOWS_PROXY',
'ALLOWS_PROXY_HTTP',
'URI_DOES_NOT_RETURN_DATA',
'URI_DANGEROUS_TO_LOAD',
'URI_IS_POTENTIALLY_TRUSTWORTHY',
],
'default_port': 443,
},
},
{
'cid': '{a181af0d-68b8-4308-94db-d4f859058215}',

Просмотреть файл

@ -12,5 +12,12 @@ Classes = [
'type': 'nsGIOProtocolHandler',
'headers': ['nsGIOProtocolHandler.h'],
'constructor': 'nsGIOProtocolHandler::GetSingleton',
'protocol_config': {
'scheme': 'moz-gio',
'flags': [
'URI_STD',
'URI_DANGEROUS_TO_LOAD',
],
},
},
]

Просмотреть файл

@ -10,5 +10,11 @@ Classes = [
'contract_ids': ['@mozilla.org/network/protocol;1?name=moz'],
'jsm': 'resource://gre/modules/MozProtocolHandler.jsm',
'constructor': 'MozProtocolHandler',
'protocol_config': {
'scheme': 'moz',
'flags': [
'URI_DANGEROUS_TO_LOAD',
],
},
},
]

Просмотреть файл

@ -19,6 +19,15 @@ Classes = [
'contract_ids': ['@mozilla.org/network/protocol;1?name=moz-anno'],
'type': 'nsAnnoProtocolHandler',
'headers': ['/toolkit/components/places/nsAnnoProtocolHandler.h'],
'protocol_config': {
'scheme': 'moz-anno',
'flags': [
'URI_NORELATIVE',
'URI_NOAUTH',
'URI_DANGEROUS_TO_LOAD',
'URI_IS_LOCAL_RESOURCE',
],
},
},
{
'cid': '{984e3259-9266-49cf-b605-60b022a00756}',
@ -82,6 +91,16 @@ Classes = [
'type': 'mozilla::places::PageIconProtocolHandler',
'headers': ['mozilla/places/PageIconProtocolHandler.h'],
'constructor': 'mozilla::places::PageIconProtocolHandler::GetSingleton',
'protocol_config': {
'scheme': 'page-icon',
'flags': [
'URI_STD',
'URI_IS_UI_RESOURCE',
'URI_IS_LOCAL_RESOURCE',
'URI_NORELATIVE',
'URI_NOAUTH',
],
},
},
{

Просмотреть файл

@ -22,6 +22,14 @@ Classes = [
'contract_ids': ['@mozilla.org/network/protocol;1?name=chrome'],
'type': 'nsChromeProtocolHandler',
'headers': ['/chrome/nsChromeProtocolHandler.h'],
'protocol_config': {
'scheme': 'chrome',
'flags': [
'URI_STD',
'URI_IS_UI_RESOURCE',
'URI_IS_LOCAL_RESOURCE',
],
},
},
{
'name': 'ChromeRegistry',

Просмотреть файл

@ -168,6 +168,8 @@ static nsresult ConstructESModuleComponent(const nsACString& aURI,
//# @js_services_table@
//# @protocol_handlers_table@
static inline bool CalledInit(size_t aIdx) {
return GetBit(gInitCalled, aIdx);
}
@ -314,6 +316,15 @@ const JSServiceEntry* JSServiceEntry::Lookup(const nsACString& aName) {
return LookupJSService(aName);
}
nsCString StaticProtocolHandler::Scheme() const {
return GetString(mScheme);
}
/* static */
const StaticProtocolHandler* StaticProtocolHandler::Lookup(const nsACString& aScheme) {
return LookupProtocolHandler(aScheme);
}
/* static */ const StaticModule* StaticComponents::LookupByCID(
const nsID& aCID) {
return ModuleByCID(aCID);

Просмотреть файл

@ -32,6 +32,8 @@ struct StaticModule;
struct StaticCategoryEntry;
struct StaticCategory;
struct StaticProtocolHandler;
extern const StaticModule gStaticModules[kStaticModuleCount];
extern const ContractEntry gContractEntries[kContractCount];
@ -40,6 +42,9 @@ extern uint8_t gInvalidContracts[kContractCount / 8 + 1];
extern const StaticCategory gStaticCategories[kStaticCategoryCount];
extern const StaticCategoryEntry gStaticCategoryEntries[];
extern const StaticProtocolHandler
gStaticProtocolHandlers[kStaticProtocolHandlerCount];
template <size_t N>
static inline bool GetBit(const uint8_t (&aBits)[N], size_t aBit) {
static constexpr size_t width = sizeof(aBits[0]) * 8;
@ -229,6 +234,25 @@ struct JSServiceEntry final {
InterfaceList Interfaces() const;
};
struct StaticProtocolHandler final {
static const StaticProtocolHandler* Lookup(const nsACString& aScheme);
static const StaticProtocolHandler& Default() {
return gStaticProtocolHandlers[kDefaultProtocolHandlerIndex];
}
StringOffset mScheme;
ModuleID mModuleID;
uint32_t mProtocolFlags;
int32_t mDefaultPort;
bool mHasDynamicFlags;
nsCString Scheme() const;
const StaticModule& Module() const {
return gStaticModules[size_t(mModuleID)];
}
};
class StaticComponents final {
public:
static const StaticModule* LookupByCID(const nsID& aCID);

Просмотреть файл

@ -13,6 +13,8 @@ NO_CONTRACT_ID = 0xFFFFFFFF
PHF_SIZE = 512
TINY_PHF_SIZE = 16
# In tests, we might not have a (complete) buildconfig.
ENDIAN = (
"<" if buildconfig.substs.get("TARGET_ENDIANNESS", "little") == "little" else ">"
@ -288,6 +290,8 @@ class ModuleEntry(object):
self.singleton = data.get("singleton", False)
self.overridable = data.get("overridable", False)
self.protocol_config = data.get("protocol_config", None)
if "name" in data:
self.anonymous = False
self.name = data["name"]
@ -596,6 +600,44 @@ class ContractEntry(object):
)
# Represents a static ProtocolHandler entry, corresponding to a C++
# ProtocolEntry struct, mapping a scheme to a static module entry and metadata.
class ProtocolHandler(object):
def __init__(self, config, module):
def error(str_):
raise Exception(
"Error defining protocol handler %s (%s): %s"
% (str(module.cid), ", ".join(map(repr, module.contract_ids)), str_)
)
self.module = module
self.scheme = config.get("scheme", None)
if self.scheme is None:
error("No scheme defined for protocol component")
self.flags = config.get("flags", None)
if self.flags is None:
error("No flags defined for protocol component")
self.default_port = config.get("default_port", -1)
self.has_dynamic_flags = config.get("has_dynamic_flags", False)
def to_cxx(self):
return """
{{
.mScheme = {scheme},
.mModuleID = {module_id},
.mProtocolFlags = {flags},
.mDefaultPort = {default_port},
.mHasDynamicFlags = {has_dynamic_flags},
}}
""".format(
scheme=strings.entry_to_cxx(self.scheme),
module_id=lower_module_id(self.module),
flags=" | ".join("nsIProtocolHandler::%s" % flag for flag in self.flags),
default_port=self.default_port,
has_dynamic_flags="true" if self.has_dynamic_flags else "false",
)
# Generates the C++ code for the StaticCategoryEntry and StaticCategory
# structs for all category entries declared in XPCOM manifests.
def gen_categories(substs, categories):
@ -820,6 +862,7 @@ def gen_substs(manifests):
contracts = []
contract_map = {}
js_services = {}
protocol_handlers = {}
jsms = set()
esModules = set()
@ -855,6 +898,12 @@ def gen_substs(manifests):
raise Exception("Duplicate JS service name: %s" % mod.js_name)
js_services[mod.js_name] = mod
if mod.protocol_config:
handler = ProtocolHandler(mod.protocol_config, mod)
if handler.scheme in protocol_handlers:
raise Exception("Duplicate protocol handler: %s" % handler.scheme)
protocol_handlers[handler.scheme] = handler
if str(mod.cid) in cids:
raise Exception("Duplicate cid: %s" % str(mod.cid))
cids.add(str(mod.cid))
@ -867,6 +916,10 @@ def gen_substs(manifests):
list(js_services.values()), PHF_SIZE, key=lambda entry: entry.js_name
)
protocol_handlers_phf = PerfectHash(
list(protocol_handlers.values()), TINY_PHF_SIZE, key=lambda entry: entry.scheme
)
js_services_json = {}
for entry in js_services.values():
for iface in entry.interfaces:
@ -880,6 +933,9 @@ def gen_substs(manifests):
substs["module_count"] = len(modules)
substs["contract_count"] = len(contracts)
substs["protocol_handler_count"] = len(protocol_handlers)
substs["default_protocol_handler_idx"] = protocol_handlers_phf.get_index("default")
gen_module_funcs(substs, module_funcs)
@ -943,6 +999,18 @@ def gen_substs(manifests):
key_length="aKey.Length()",
)
substs["protocol_handlers_table"] = protocol_handlers_phf.cxx_codegen(
name="LookupProtocolHandler",
entry_type="StaticProtocolHandler",
entries_name="gStaticProtocolHandlers",
lower_entry=lambda entry: entry.to_cxx(),
return_type="const StaticProtocolHandler*",
return_entry="return entry.Scheme() == aKey ? &entry : nullptr;",
key_type="const nsACString&",
key_bytes="aKey.BeginReading()",
key_length="aKey.Length()",
)
substs["js_services_json"] = json.dumps(js_services_json, sort_keys=True, indent=4)
# Do this only after everything else has been emitted so we're sure the
@ -1022,6 +1090,10 @@ static constexpr size_t kStaticCategoryCount = %(category_count)d;
static constexpr size_t kModuleInitCount = %(init_count)d;
static constexpr size_t kStaticProtocolHandlerCount = %(protocol_handler_count)d;
static constexpr size_t kDefaultProtocolHandlerIndex = %(default_protocol_handler_idx)d;
} // namespace xpcom
} // namespace mozilla

Просмотреть файл

@ -25,6 +25,10 @@ class TestGenStaticComponents(unittest.TestCase):
"categories": {
"dummy1": ["m-dummy1", "m-dummy2"],
},
"protocol_config": {
"scheme": "dummy",
"flags": [],
},
}
substs = gen_static_components.gen_substs([{"Classes": [clas]}])
@ -65,6 +69,10 @@ class TestGenStaticComponents(unittest.TestCase):
"name": ["m-dummy1", "m-dummy2"],
},
},
"protocol_config": {
"scheme": "dummy",
"flags": [],
},
}
substs = gen_static_components.gen_substs([{"Classes": [clas]}])
@ -106,6 +114,10 @@ class TestGenStaticComponents(unittest.TestCase):
"backgroundtasks": BackgroundTasksSelector.ALL_TASKS,
},
},
"protocol_config": {
"scheme": "dummy",
"flags": [],
},
}
substs = gen_static_components.gen_substs([{"Classes": [clas]}])