Bug 350629 - GeneratePrefix can return prefixes which begin with "xml" or similar, even though such prefixes are reserved in the XML spec. r=brendan

This commit is contained in:
jwalden%mit.edu 2006-09-04 23:25:29 +00:00
Родитель 33e35afd71
Коммит 2542519660
1 изменённых файлов: 37 добавлений и 3 удалений

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

@ -2502,6 +2502,20 @@ GeneratePrefix(JSContext *cx, JSString *uri, JSXMLArray *decls)
JS_ASSERT(!IS_EMPTY(uri));
/*
* If there are no *declared* namespaces, skip all collision detection and
* return a short prefix quickly; an example of such a situation:
*
* var x = <f/>;
* var n = new Namespace("http://example.com/");
* x.@n::att = "val";
* x.toXMLString();
*
* This is necessary for various log10 uses below to be valid.
*/
if (decls->length == 0)
return JS_NewStringCopyZ(cx, "a");
/*
* Try peeling off the last filename suffix or pathname component till
* we have a valid XML name. This heuristic will prefer "xul" given
@ -2513,20 +2527,40 @@ GeneratePrefix(JSContext *cx, JSString *uri, JSXMLArray *decls)
while (--cp > start) {
if (*cp == '.' || *cp == '/' || *cp == ':') {
++cp;
if (IsXMLName(cp, PTRDIFF(end, cp, jschar)))
length = PTRDIFF(end, cp, jschar);
if (IsXMLName(cp, length) && !STARTS_WITH_XML(cp, length))
break;
end = --cp;
}
}
length = PTRDIFF(end, cp, jschar);
/*
* If the namespace consisted only of non-XML names or names that begin
* case-insensitively with "xml", arbitrarily create a prefix consisting of
* 'a's of size length (allowing dp-calculating code to work with or without
* this branch executing) plus the space for storing a hyphen and the serial
* number (avoiding reallocation if a collision happens).
*/
bp = (jschar *) cp;
newlength = length;
if (STARTS_WITH_XML(cp, length) || !IsXMLName(cp, length)) {
newlength = length + 2 + (size_t) log10(decls->length);
bp = (jschar *)
JS_malloc(cx, (newlength + 1) * sizeof(jschar));
if (!bp)
return NULL;
bp[newlength] = 0;
for (i = 0; i < newlength; i++)
bp[i] = 'a';
}
/*
* Now search through decls looking for a collision. If we collide with
* an existing prefix, start tacking on a hyphen and a serial number.
*/
serial = 0;
bp = (jschar *) cp;
newlength = length;
do {
done = JS_TRUE;
for (i = 0, n = decls->length; i < n; i++) {