зеркало из https://github.com/mozilla/gecko-dev.git
bug 191856, string usage in txExpandedName::init, r=sicking, sr=peterv
This commit is contained in:
Родитель
3c5bd439a2
Коммит
a58689db6c
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
* The contents of this file are subject to the Mozilla Public
|
* The contents of this file are subject to the Mozilla Public
|
||||||
* License Version 1.1 (the "License"); you may not use this file
|
* License Version 1.1 (the "License"); you may not use this file
|
||||||
* except in compliance with the License. You may obtain a copy of
|
* except in compliance with the License. You may obtain a copy of
|
||||||
|
@ -34,25 +34,108 @@
|
||||||
#include "txAtoms.h"
|
#include "txAtoms.h"
|
||||||
#include "txStringUtils.h"
|
#include "txStringUtils.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for checking and partioning of QNames
|
||||||
|
*/
|
||||||
|
class txQNameParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum QResult {
|
||||||
|
eBrokenName,
|
||||||
|
eOneName,
|
||||||
|
eTwoNames
|
||||||
|
};
|
||||||
|
QResult parse(const nsAString::const_iterator& aStart,
|
||||||
|
const nsAString::const_iterator& aEnd);
|
||||||
|
nsAString::const_iterator mColon;
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
eInitial,
|
||||||
|
ePrefixNC,
|
||||||
|
eColon,
|
||||||
|
eNameNC,
|
||||||
|
eBroken
|
||||||
|
} mState;
|
||||||
|
};
|
||||||
|
|
||||||
|
txQNameParser::QResult
|
||||||
|
txQNameParser::parse(const nsAString::const_iterator& aStart,
|
||||||
|
const nsAString::const_iterator& aEnd)
|
||||||
|
{
|
||||||
|
nsAString::const_iterator chunk(aStart);
|
||||||
|
mState = eInitial;
|
||||||
|
|
||||||
|
PRUint32 size = 0, i = 0;
|
||||||
|
for ( ; chunk != aEnd; chunk.advance(size)) {
|
||||||
|
const PRUnichar* buf = chunk.get();
|
||||||
|
size = chunk.size_forward();
|
||||||
|
|
||||||
|
// fragment at 'buf' is 'size' characters long
|
||||||
|
for (i = 0; i < size; ++i) {
|
||||||
|
const PRUnichar ch = buf[i];
|
||||||
|
switch(mState) {
|
||||||
|
case eInitial:
|
||||||
|
mState = XMLUtils::isLetter(ch) ? ePrefixNC : eBroken;
|
||||||
|
break;
|
||||||
|
case ePrefixNC:
|
||||||
|
if (ch == ':') {
|
||||||
|
mState = eColon;
|
||||||
|
mColon = chunk;
|
||||||
|
mColon.advance(i);
|
||||||
|
}
|
||||||
|
else if (!XMLUtils::isNCNameChar(ch)) {
|
||||||
|
mState = eBroken;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case eColon:
|
||||||
|
mState = XMLUtils::isLetter(ch) ? eNameNC : eBroken;
|
||||||
|
break;
|
||||||
|
case eNameNC:
|
||||||
|
if (!XMLUtils::isNCNameChar(ch)) {
|
||||||
|
mState = eBroken;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NS_WARNING("Should not happen");
|
||||||
|
}
|
||||||
|
if (mState == eBroken) {
|
||||||
|
return eBrokenName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mState == eNameNC) {
|
||||||
|
return eTwoNames;
|
||||||
|
}
|
||||||
|
if (mState == ePrefixNC) {
|
||||||
|
return eOneName;
|
||||||
|
}
|
||||||
|
return eBrokenName;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult txExpandedName::init(const nsAString& aQName,
|
nsresult txExpandedName::init(const nsAString& aQName,
|
||||||
Node* aResolver,
|
Node* aResolver,
|
||||||
MBool aUseDefault)
|
MBool aUseDefault)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aResolver, "missing resolve node");
|
NS_ASSERTION(aResolver, "missing resolve node");
|
||||||
if (!XMLUtils::isValidQName(PromiseFlatString(aQName)))
|
nsAString::const_iterator start, end;
|
||||||
return NS_ERROR_FAILURE;
|
aQName.BeginReading(start);
|
||||||
|
aQName.EndReading(end);
|
||||||
|
txQNameParser p;
|
||||||
|
txQNameParser::QResult qr = p.parse(start, end);
|
||||||
|
|
||||||
PRInt32 idx = aQName.FindChar(':');
|
if (qr == txQNameParser::eBrokenName) {
|
||||||
if (idx != kNotFound) {
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qr == txQNameParser::eTwoNames) {
|
||||||
nsCOMPtr<nsIAtom> prefix =
|
nsCOMPtr<nsIAtom> prefix =
|
||||||
do_GetAtom(Substring(aQName, 0, (PRUint32)idx));
|
do_GetAtom(Substring(start, p.mColon));
|
||||||
PRInt32 namespaceID = aResolver->lookupNamespaceID(prefix);
|
PRInt32 namespaceID = aResolver->lookupNamespaceID(prefix);
|
||||||
if (namespaceID == kNameSpaceID_Unknown)
|
if (namespaceID == kNameSpaceID_Unknown)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
mNamespaceID = namespaceID;
|
mNamespaceID = namespaceID;
|
||||||
|
|
||||||
mLocalName = do_GetAtom(Substring(aQName, (PRUint32)idx + 1,
|
mLocalName = do_GetAtom(Substring(++p.mColon, end));
|
||||||
aQName.Length() - (idx + 1)));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mLocalName = do_GetAtom(aQName);
|
mLocalName = do_GetAtom(aQName);
|
||||||
|
@ -98,44 +181,15 @@ void XMLUtils::getLocalPart(const nsAString& src, nsIAtom** dest)
|
||||||
*dest = NS_NewAtom(getLocalPart(src));
|
*dest = NS_NewAtom(getLocalPart(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
MBool XMLUtils::isValidQName(const nsAFlatString& aName)
|
MBool XMLUtils::isValidQName(const nsAString& aName)
|
||||||
{
|
{
|
||||||
if (aName.IsEmpty()) {
|
nsAString::const_iterator start, end;
|
||||||
return MB_FALSE;
|
aName.BeginReading(start);
|
||||||
}
|
aName.EndReading(end);
|
||||||
|
txQNameParser p;
|
||||||
|
txQNameParser::QResult qr = p.parse(start, end);
|
||||||
|
|
||||||
if (!isLetter(aName.CharAt(0))) {
|
return qr != txQNameParser::eBrokenName;
|
||||||
return MB_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRUint32 size = aName.Length();
|
|
||||||
PRUint32 i;
|
|
||||||
MBool foundColon = MB_FALSE;
|
|
||||||
for (i = 1; i < size; ++i) {
|
|
||||||
PRUnichar character = aName.CharAt(i);
|
|
||||||
if (character == ':') {
|
|
||||||
foundColon = MB_TRUE;
|
|
||||||
++i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!isNCNameChar(character)) {
|
|
||||||
return MB_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == size) {
|
|
||||||
// If we found a colon as the last letter it is not
|
|
||||||
// a valid QName.
|
|
||||||
return !foundColon;
|
|
||||||
}
|
|
||||||
if (!isLetter(aName.CharAt(i))) {
|
|
||||||
return MB_FALSE;
|
|
||||||
}
|
|
||||||
for (++i; i < size; ++i) {
|
|
||||||
if (!isNCNameChar(aName.CharAt(i))) {
|
|
||||||
return MB_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return MB_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
* The contents of this file are subject to the Mozilla Public
|
* The contents of this file are subject to the Mozilla Public
|
||||||
* License Version 1.1 (the "License"); you may not use this file
|
* License Version 1.1 (the "License"); you may not use this file
|
||||||
* except in compliance with the License. You may obtain a copy of
|
* except in compliance with the License. You may obtain a copy of
|
||||||
|
@ -94,7 +94,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Returns true if the given string is a valid XML QName
|
* Returns true if the given string is a valid XML QName
|
||||||
*/
|
*/
|
||||||
static MBool isValidQName(const nsAFlatString& aName);
|
static MBool isValidQName(const nsAString& aName);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns true if the given character is whitespace.
|
* Returns true if the given character is whitespace.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче