Last Comment Bug 565480 - XML parsing errors are reported with URL=moz-nullprincipal:{...} when using Components.classes ["@mozilla.org/xmlextras/domparser;1"].createInstance (Components.interfaces.nsIDOMParser), correct URL with the DOMParser constructor
: XML parsing errors are reported with URL=moz-nullprincipal:{...} when using C...
Status: RESOLVED INVALID
:
Product: Core
Classification: Components
Component: XML (show other bugs)
: Trunk
: x86 Mac OS X
: -- normal (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
:
: Andrew Overholt [:overholt]
Mentors:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-05-12 15:16 PDT by Nickolay_Ponomarev
Modified: 2010-05-22 15:16 PDT (History)
1 user (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments

Description Nickolay_Ponomarev 2010-05-12 15:16:45 PDT
1) Running this in Error Console:
(new DOMParser()).parseFromString("<a></b>", "text/xml")

..prints this in the Error Conole:

Error: mismatched tag. Expected: </a>.
Source File: about:blank
Line: 1, Column: 6
Source Code:
<a></b>

2) But running this:
Components.classes["@mozilla.org/xmlextras/domparser;1"].
    createInstance(Components.interfaces.nsIDOMParser).
    parseFromString("<a></b>", "text/xml")

..prints:

Error: mismatched tag. Expected: </a>.
Source File: moz-nullprincipal:{eafaf4ef-1b8a-f646-aa76-a2f4827e049d}
Line: 1, Column: 6
Source Code:
<a></b>

Notice the incorrect URL.

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.3a5pre) Gecko/20100511 Minefield/3.7a5pre
Comment 1 Boris Zbarsky [:bz] (still a bit busy) 2010-05-12 20:35:32 PDT
Yep.  You never called init() on the parser.  Please read nsIDOMParser.idl towards the bottom.
Comment 2 Nickolay_Ponomarev 2010-05-14 12:31:48 PDT
Thanks. A clarification: I'm not writing the code, this bug is a result of me deciphering a message this approach ends up sending to the Error console (bug 501838). Apparently, I'm not the only one who didn't read the IDL.

I'm fine with this being invalid, but I'd like to learn a little more about this if it doesn't take too much of your time.

I read bug 332840 which added init() to nsIDOMParser, but I don't see why the default for creating the DOM parser using the DOMParser constructor is different from creating it using createInstance. Is it bug 332840 comment 15 + 16?

Why should someone parsing XML care what principal to use and how should one pick it (as you say yourself in bug 332840 comment 19)? Can something bad happen if we use new DOMParser() (which presumably uses some highly privileged principal, I'm not sure what exactly)? This information is notably absent from both the IDL and the docs https://developer.mozilla.org/en/DOMParser ...
Comment 3 Boris Zbarsky [:bz] (still a bit busy) 2010-05-14 12:47:45 PDT
> but I don't see why the default for creating the DOM parser using the
> DOMParser constructor is different from creating it using createInstance.

Because in the former case the DOM parser knows who created it (or rather, which Window object's |new DOMParser()| method was called.  When creating using createInstance, that information is not available; there is no way to tell "who" exactly is creating the parser.  So in that case, it's the creator's responsibility to provide that information.  I really wish we could just deduce it automagically, but there's no sane way to do that.

> Why should someone parsing XML care what principal to use and how should one
> pick it

As you point out, this is hard to answer in generality.  In general the principal is our "who is acting" identifier; the reason to care is if you want to create objects that some particular set of unprivileged code will be able to access (if you're calling init(), then you ourself are clearly privileged).  But note that the init() method allows providing a URI, not just a principal and it's the URI that's used for the error report; it's just that the default URI used if nothing is provided is the URI of the default principal, which is a null principal because the DOMParser has no information on what else to use.

> Can something bad happen if we use new DOMParser() (which presumably uses
> some highly privileged principal, I'm not sure what exactly)?

DOMParser will never use the system principal; if you use new DOMParser in chrome it'll use a null principal instead (but still use your window's chrome:// URI as the URI).

Does that help?
Comment 4 Nickolay_Ponomarev 2010-05-14 15:20:51 PDT
(This gets a little longer discussion than I anticipated, but I'd like to update the docs since I already started asking, so here we go..) 

> DOMParser will never use the system principal; if you use new DOMParser in
> chrome it'll use a null principal instead (but still use your window's
> chrome:// URI as the URI).

Hmm, that contradicts https://developer.mozilla.org/en/DOMParser ("When a DOMParser is instantiated by calling new DOMParser(), it inherits the calling code's principal") and maybe bug 332840 comment 6 ("we create a document with a null principal but try to set a base URI on it, which is not kosher.  And security manager blocks it"), unless it's only not kosher to set base URI [and it's fine to set the document URI] with the null principal.

Are those comments outdated and it's in fact OK to use the null principal while providing a document URI (+same question for base URI)?

> the reason to care [about the principal to give to DOMParser] is if you want
> to create objects that some particular set of unprivileged code will be able
> to access
Access in what sense? I can think of two cases -- giving references to the nodes in the parsed DOM to unprivileged JS directly and appending it to the DOM of unprivileged JS. Unless I messed up when testing[1], both cases don't compare principals. What did I miss?

bug 332840 comment 17 also talks about the situation when "someone parses a DOM that contains, say, and image pointing to some URI" -- my understanding was that the DOM parsed via DOMParser is blocked from doing any actions, which seems to be confirmed later in that comment, so the principal doesn't matter for these cases?

[1] I ran variations of this in a chrome context on the trunk build:
//var principal = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
var c = new DOMParser(/* { principal | null | <nothing> } */).parseFromString("<a></a>", "text/xml").firstChild
// getting the dynamic document in http://htmledit.squarefree.com/
var d = content.document.getElementsByTagName("FRAME")[1].contentDocument
d.defaultView.functionDefinedInContentThatAlertsItsParameter(c)
d.documentElement.appendChild(c)
Comment 5 Boris Zbarsky [:bz] (still a bit busy) 2010-05-14 17:55:18 PDT
> (This gets a little longer discussion than I anticipated, but I'd like to
> update the docs

Excellent.

> Hmm, that contradicts https://developer.mozilla.org/en/DOMParser ("When a
> DOMParser is instantiated by calling new DOMParser(), it inherits the calling
> code's principal")

Well, that page is wrong, in the chrome case.  ;)

> unless it's only not kosher to set base URI [and it's fine to set the
> document URI]

At the time, nsIDocument::SetBaseURI had a security check in it that checked that the document's principal could load (in the CheckLoadURI sense) the new base URI.  Null principals can't load anything, so this gave errors.

> Are those comments outdated and it's in fact OK to use the null principal
> while providing a document URI (+same question for base URI)?

At this point, on trunk only, yes.

Note that what DOMParser does to work around the security check (and we should remove this code on trunk) is use the "real" principal while setting the base URI, then switch to the null principal if the real principal is system.  See the code at http://hg.mozilla.org/mozilla-central/file/ed5fdfcd9e68/content/base/src/nsDOMParser.cpp#l225

> Unless I messed up when testing[1], both cases don't compare principals. What
> did I miss?

Hmm.  Both used to have security checks.  It's possible that the append check got removed and the other replaced with wrapperization...

> my understanding was that the DOM parsed via DOMParser is blocked from doing
> any actions

The blocking mechanism uses generic hooks which don't get called if the principal involved is system.  The context of bug 332840 comment 17 was specifically the case when the domparser has the null principal.
Comment 6 Boris Zbarsky [:bz] (still a bit busy) 2010-05-14 17:55:51 PDT
And to be clear, please ask if you have more questions!
Comment 7 Nickolay_Ponomarev 2010-05-22 15:16:44 PDT
Since we don't know when exactly these values matter, I updated the page to stop lying about the principal of new DOMParser() in chrome and added the text saying that you don't usually care about principals and URIs except for the case this bug is about and the general area of "creat[ing] objects that some particular set of unprivileged code will be able to access".
https://developer.mozilla.org/en/DOMParser

Thanks for your help!

Note You need to log in before you can comment on or make changes to this bug.