biolizard89 wrote:So, I see 4 ways to approach the "import subdomain" issue.
- Have entirely separate import logic per namespace, e.g. implying the traversal of the "map" field. This appears to be what Hugo is suggesting.
- Have a namespace-specific set of contexts where "import" can appear.
- Have a namespace-specific name for the "import" field. For d/ this could be something that isn't a valid domain label.
- Make "import" global regardless of namespace, with a name that doesn't collide with anything.
These are in decreasing complexity of implementation.
Option 2 seems to be uniformly simpler than Option 1, and I don't see any problem with it.
Option 3 will impose the restriction that no field in a namespace spec can accept arbitrary keys for dicts. In my opinion it doesn't make sense for a namespace to accept arbitrary data in any form, since base64 is better suited for that.
Option 4 will impose a restriction on the character set of all namespaces. To be honest, I don't see a problem here either. There are a few specific applications that Namecoin targets, and very few of them, if any, need the full character set. For example, the following rules could be used:
- Don't reserve anything that has a meaning in a DNS name or a URL.
- Don't reserve anything that has a meaning in common identity formats, e.g. real names, email addresses, etc.
- Don't reserve anything that has a meaning in base64 encoding.
A more thorough list could (and should) be put together. From these rules, find a specific prefix to reserve for JSON operations, such as importing, decrypting, expiring, etc. Any namespace that actually needs that prefix is clearly a weird use case, and can use base64 to encode it.
Thoughts on this? Phelix, Hugo, Daniel?
Firstly, the case for generic import is substantially diminished by the lack of namespaces. Namecoin currently has two official namespaces. We're not facing an excess of namespaces such that a generic import functionality is urgently necessary.
Secondly, this discussion regards the specification, not any implementation of it. So if an implementor finds that they can reuse code for import processing for several domains, nothing stops them. But each namespace specification should have the discretion of expressing its own import processing rules and semantics. To do otherwise necessarily imposes semantics on future namespaces, which may negatively impact the adaptability of Namecoin to new problem spaces.
Moreover, I can't see any situation in which import needs to be processed by an entity which doesn't understand the semantics of the namespace. All import processing will already be done by a piece of software that comprehends the namespace. So generic import isn't necessary from an ecosystem perspective, and may introduce security considerations. If you add generic import to Namecoin value semantics, Namecoin values aren't really JSON anymore; they're a sort of super-JSON, but people will expect it to function like JSON, which may lead to injection attacks.
The id/ namespace specifies the following syntax:
Code: Select all
"email":
{
"default": "khal@dot-bit.org",
"business": "khal@example.com"
}
There may be all sorts of applications which generate values programmatically, either in a user-initiated or automated fashion. What if the user specifies a key of 'import'? Yes, you can introduce an escaping rule, but this emphasises the fact that you're not dealing with JSON anymore, but a sort of modified JSON which (dangerously) can be formed by a JSON serializer, but not necessarily with the same semantics. This essentially introduces the potential for injection vulnerabilities. Given the ridiculous prevalence of injection vulnerabilities even today, this seems a foolish move.
Relying on the premise that people won't specify "unusal" key names like "@$()!>,?#import^*" isn't sufficient, because the assumption that key names are always structual (something like an XML tag name) rather than constituting content is false (which doesn't necessarily mean the content isn't textual, which makes the use of base64 silly.) If there exists a JSON format specification
x today, or tomorrow, and it models something which would be useful in Namecoin (identity is such a complex issue it's easy to imagine formats which would be useful with id/), it's potentially unusable, because it's specified in JSON and not the subset of it to which Namecoin assigns neutral semantics. So you then end up having to modify that specification in a Namecoin-specific way, such as the proposal to base64-encode keys... which is terrible, since it makes the format machine unreadable, requires changes to the format, and introduces an element of context (did this structure come from Namecoin so I need to de-frobnicate the keys, or should it be taken as is?) This sort of context is undesirable and increases complexity. If the "came from Namecoin" bit gets set wrong (due to a bug or whatever) this could cause misinterpretation of the data, which coud have security implications. It is also incredibly likely that some people setting up keys will inevitably fail to do the frobnication, or do it wrong, which will encourage implementations (however inadvisably) to try and 'guess' whether it needs to defrobnicate the keys or not, which is even more dangerous.
Moreover, completely independent of the method of activation for generic import, its operation obliges any format or subformat used with any namespace to be semantically compatible with the merge rules it defines. It is logically impossible for such merge rules to comply with all possible JSON formats (unless you make import so complicated it starts looking like a generic transformation language ala XSLT, which is a road we surely don't want to go down.)
Case in point. Here is format A:
Code: Select all
{
"administrative-contact": {
"name": "John Smith",
"email": "jsmith@example.com",
"tel": "+1.222.3333333",
},
}
This is imported by another value:
Code: Select all
{
"administrative-contact": {
"name": "Jane Doe",
"email": "jdoe@example.com",
"fax": "+1.333.4444444"
},
"import": "..."
}
So what is the correct result? If we merge maps in a generic occluding manner, we might get this:
Code: Select all
{
"administrative-contact": {
"name": "Jane Doe",
"email": "jdoe@example.com",
"tel": "+1.222.3333333",
"fax": "+1.333.4444444"
}
Oops - if I try and call Jane Doe, I'm going to end up calling John Smith instead.
Occlusion via explicitly specifying 'null' is one possible means of resolution, but this is impractical for formats which list a large number of possible item types.
If you make maps get wholly replaced with one another, that fixes the above but breaks many useful d/ cases.
Ultimately generic import is complicated. It might be worth considering, despite its complexity and issues, if we were facing dozens of namespaces awaiting realization. But we have only two. The complexity of import exceeds the gains you make by it. And again, this purely concerns the standard; people are free to factor their implementation as they see fit, so long as they conform with the standard.