зеркало из https://github.com/mozilla/gecko-dev.git
Bug 792790 - Introduce NoBoundsCheck variants of accessors on nsHtml5HtmlAttributes; Make operator= in jArray nullptr-aware. r=smaug.
This commit is contained in:
Родитель
4649363c2e
Коммит
b70e7be378
|
@ -23,6 +23,7 @@
|
|||
#ifndef jArray_h_
|
||||
#define jArray_h_
|
||||
|
||||
#include "mozilla/NullPtr.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
template<class T, class L>
|
||||
|
@ -99,11 +100,24 @@ class autoJArray {
|
|||
arr = other.arr;
|
||||
length = other.length;
|
||||
}
|
||||
void operator=(L zero) {
|
||||
#if defined(__clang__)
|
||||
// clang on OS X 10.7 does not have std::nullptr_t
|
||||
typedef decltype(nullptr) jArray_nullptr_t;
|
||||
#elif defined(MOZ_HAVE_CXX11_NULLPTR)
|
||||
// decltype(nullptr) does not evaluate to std::nullptr_t on GCC 4.6.3
|
||||
typedef std::nullptr_t jArray_nullptr_t;
|
||||
#elif defined(__GNUC__)
|
||||
typedef void* jArray_nullptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef uint64_t jArray_nullptr_t;
|
||||
#else
|
||||
typedef uint32_t jArray_nullptr_t;
|
||||
#endif
|
||||
void operator=(jArray_nullptr_t zero) {
|
||||
// Make assigning null to an array in Java delete the buffer in C++
|
||||
NS_ASSERTION(!zero, "Non-zero integer assigned to jArray.");
|
||||
// MSVC10 does not allow asserting that zero is null.
|
||||
delete[] arr;
|
||||
arr = 0;
|
||||
arr = nullptr;
|
||||
length = 0;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -131,8 +131,94 @@ public final class HtmlAttributes implements Attributes {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use with static argument.
|
||||
*
|
||||
* @see org.xml.sax.Attributes#getValue(java.lang.String)
|
||||
*/
|
||||
public String getValue(AttributeName name) {
|
||||
int index = getIndex(name);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getValueNoBoundsCheck(index);
|
||||
}
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getLocalName(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the local name at index
|
||||
*/
|
||||
public @Local String getLocalNameNoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return names[index].getLocal(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getURI(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the namespace URI at index
|
||||
*/
|
||||
public @NsUri String getURINoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return names[index].getUri(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getPrefix(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the namespace prefix at index
|
||||
*/
|
||||
public @Prefix String getPrefixNoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return names[index].getPrefix(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getValue(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the attribute value at index
|
||||
*/
|
||||
public String getValueNoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return values[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getAttributeName(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the attribute name at index
|
||||
*/
|
||||
public AttributeName getAttributeNameNoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return names[index];
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
/**
|
||||
* Variant of <code>getQName(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the QName at index
|
||||
*/
|
||||
public @QName String getQNameNoBoundsCheck(int index) {
|
||||
return names[index].getQName(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getType(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the attribute type at index
|
||||
*/
|
||||
public @IdType String getTypeNoBoundsCheck(int index) {
|
||||
return (names[index] == AttributeName.ID) ? "ID" : "CDATA";
|
||||
}
|
||||
|
||||
public int getIndex(String qName) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (names[i].getQName(mode).equals(qName)) {
|
||||
|
@ -188,12 +274,6 @@ public final class HtmlAttributes implements Attributes {
|
|||
}
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public @Local String getLocalName(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getLocal(mode);
|
||||
|
@ -201,8 +281,6 @@ public final class HtmlAttributes implements Attributes {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
public @QName String getQName(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
|
@ -220,8 +298,6 @@ public final class HtmlAttributes implements Attributes {
|
|||
}
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
public AttributeName getAttributeName(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index];
|
||||
|
@ -254,22 +330,6 @@ public final class HtmlAttributes implements Attributes {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use with static argument.
|
||||
*
|
||||
* @see org.xml.sax.Attributes#getValue(java.lang.String)
|
||||
*/
|
||||
public String getValue(AttributeName name) {
|
||||
int index = getIndex(name);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getValue(index);
|
||||
}
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
public String getId() {
|
||||
return idValue;
|
||||
}
|
||||
|
@ -518,9 +578,9 @@ public final class HtmlAttributes implements Attributes {
|
|||
public void merge(HtmlAttributes attributes) throws SAXException {
|
||||
int len = attributes.getLength();
|
||||
for (int i = 0; i < len; i++) {
|
||||
AttributeName name = attributes.getAttributeName(i);
|
||||
AttributeName name = attributes.getAttributeNameNoBoundsCheck(i);
|
||||
if (!contains(name)) {
|
||||
addAttribute(name, attributes.getValue(i), XmlViolationPolicy.ALLOW);
|
||||
addAttribute(name, attributes.getValueNoBoundsCheck(i), XmlViolationPolicy.ALLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2143,7 +2143,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
|||
if (actionIndex > -1) {
|
||||
formAttrs.addAttribute(
|
||||
AttributeName.ACTION,
|
||||
attributes.getValue(actionIndex)
|
||||
attributes.getValueNoBoundsCheck(actionIndex)
|
||||
// [NOCPP[
|
||||
, XmlViolationPolicy.ALLOW
|
||||
// ]NOCPP]
|
||||
|
@ -2158,7 +2158,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
|||
HtmlAttributes.EMPTY_ATTRIBUTES);
|
||||
int promptIndex = attributes.getIndex(AttributeName.PROMPT);
|
||||
if (promptIndex > -1) {
|
||||
@Auto char[] prompt = Portability.newCharArrayFromString(attributes.getValue(promptIndex));
|
||||
@Auto char[] prompt = Portability.newCharArrayFromString(attributes.getValueNoBoundsCheck(promptIndex));
|
||||
appendCharacters(stack[currentPtr].node,
|
||||
prompt, 0, prompt.length);
|
||||
} else {
|
||||
|
@ -2174,14 +2174,14 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
|||
// ]NOCPP]
|
||||
);
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
AttributeName attributeQName = attributes.getAttributeName(i);
|
||||
AttributeName attributeQName = attributes.getAttributeNameNoBoundsCheck(i);
|
||||
if (AttributeName.NAME == attributeQName
|
||||
|| AttributeName.PROMPT == attributeQName) {
|
||||
attributes.releaseValue(i);
|
||||
} else if (AttributeName.ACTION != attributeQName) {
|
||||
inputAttributes.addAttribute(
|
||||
attributeQName,
|
||||
attributes.getValue(i)
|
||||
attributes.getValueNoBoundsCheck(i)
|
||||
// [NOCPP[
|
||||
, XmlViolationPolicy.ALLOW
|
||||
// ]NOCPP]
|
||||
|
|
|
@ -84,62 +84,6 @@ nsHtml5HtmlAttributes::getIndex(nsHtml5AttributeName* name)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsHtml5HtmlAttributes::getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
nsHtml5HtmlAttributes::getLocalName(int32_t index)
|
||||
{
|
||||
if (index < length && index >= 0) {
|
||||
return names[index]->getLocal(mode);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsHtml5AttributeName*
|
||||
nsHtml5HtmlAttributes::getAttributeName(int32_t index)
|
||||
{
|
||||
if (index < length && index >= 0) {
|
||||
return names[index];
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsHtml5HtmlAttributes::getURI(int32_t index)
|
||||
{
|
||||
if (index < length && index >= 0) {
|
||||
return names[index]->getUri(mode);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
nsHtml5HtmlAttributes::getPrefix(int32_t index)
|
||||
{
|
||||
if (index < length && index >= 0) {
|
||||
return names[index]->getPrefix(mode);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsString*
|
||||
nsHtml5HtmlAttributes::getValue(int32_t index)
|
||||
{
|
||||
if (index < length && index >= 0) {
|
||||
return values[index];
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsString*
|
||||
nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* name)
|
||||
{
|
||||
|
@ -147,10 +91,51 @@ nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* name)
|
|||
if (index == -1) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return getValue(index);
|
||||
return getValueNoBoundsCheck(index);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsHtml5HtmlAttributes::getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
nsHtml5HtmlAttributes::getLocalNameNoBoundsCheck(int32_t index)
|
||||
{
|
||||
|
||||
return names[index]->getLocal(mode);
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsHtml5HtmlAttributes::getURINoBoundsCheck(int32_t index)
|
||||
{
|
||||
|
||||
return names[index]->getUri(mode);
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
nsHtml5HtmlAttributes::getPrefixNoBoundsCheck(int32_t index)
|
||||
{
|
||||
|
||||
return names[index]->getPrefix(mode);
|
||||
}
|
||||
|
||||
nsString*
|
||||
nsHtml5HtmlAttributes::getValueNoBoundsCheck(int32_t index)
|
||||
{
|
||||
|
||||
return values[index];
|
||||
}
|
||||
|
||||
nsHtml5AttributeName*
|
||||
nsHtml5HtmlAttributes::getAttributeNameNoBoundsCheck(int32_t index)
|
||||
{
|
||||
|
||||
return names[index];
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* name, nsString* value)
|
||||
{
|
||||
|
|
|
@ -69,13 +69,13 @@ class nsHtml5HtmlAttributes
|
|||
nsHtml5HtmlAttributes(int32_t mode);
|
||||
~nsHtml5HtmlAttributes();
|
||||
int32_t getIndex(nsHtml5AttributeName* name);
|
||||
int32_t getLength();
|
||||
nsIAtom* getLocalName(int32_t index);
|
||||
nsHtml5AttributeName* getAttributeName(int32_t index);
|
||||
int32_t getURI(int32_t index);
|
||||
nsIAtom* getPrefix(int32_t index);
|
||||
nsString* getValue(int32_t index);
|
||||
nsString* getValue(nsHtml5AttributeName* name);
|
||||
int32_t getLength();
|
||||
nsIAtom* getLocalNameNoBoundsCheck(int32_t index);
|
||||
int32_t getURINoBoundsCheck(int32_t index);
|
||||
nsIAtom* getPrefixNoBoundsCheck(int32_t index);
|
||||
nsString* getValueNoBoundsCheck(int32_t index);
|
||||
nsHtml5AttributeName* getAttributeNameNoBoundsCheck(int32_t index);
|
||||
void addAttribute(nsHtml5AttributeName* name, nsString* value);
|
||||
void clear(int32_t m);
|
||||
void releaseValue(int32_t i);
|
||||
|
|
|
@ -3906,8 +3906,8 @@ nsHtml5Tokenizer::emitOrAppendOne(const PRUnichar* val, int32_t returnState)
|
|||
void
|
||||
nsHtml5Tokenizer::end()
|
||||
{
|
||||
strBuf = 0;
|
||||
longStrBuf = 0;
|
||||
strBuf = nullptr;
|
||||
longStrBuf = nullptr;
|
||||
doctypeName = nullptr;
|
||||
if (systemIdentifier) {
|
||||
nsHtml5Portability::releaseString(systemIdentifier);
|
||||
|
|
|
@ -548,7 +548,7 @@ nsHtml5TreeBuilder::endTokenization()
|
|||
stack[currentPtr]->release();
|
||||
currentPtr--;
|
||||
}
|
||||
stack = 0;
|
||||
stack = nullptr;
|
||||
}
|
||||
if (listOfActiveFormattingElements) {
|
||||
while (listPtr > -1) {
|
||||
|
@ -557,9 +557,9 @@ nsHtml5TreeBuilder::endTokenization()
|
|||
}
|
||||
listPtr--;
|
||||
}
|
||||
listOfActiveFormattingElements = 0;
|
||||
listOfActiveFormattingElements = nullptr;
|
||||
}
|
||||
charBuffer = 0;
|
||||
charBuffer = nullptr;
|
||||
end();
|
||||
}
|
||||
|
||||
|
@ -1132,14 +1132,14 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
|
|||
nsHtml5HtmlAttributes* formAttrs = new nsHtml5HtmlAttributes(0);
|
||||
int32_t actionIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_ACTION);
|
||||
if (actionIndex > -1) {
|
||||
formAttrs->addAttribute(nsHtml5AttributeName::ATTR_ACTION, attributes->getValue(actionIndex));
|
||||
formAttrs->addAttribute(nsHtml5AttributeName::ATTR_ACTION, attributes->getValueNoBoundsCheck(actionIndex));
|
||||
}
|
||||
appendToCurrentNodeAndPushFormElementMayFoster(formAttrs);
|
||||
appendVoidElementToCurrentMayFoster(nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
|
||||
appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName::ELT_LABEL, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
|
||||
int32_t promptIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_PROMPT);
|
||||
if (promptIndex > -1) {
|
||||
autoJArray<PRUnichar,int32_t> prompt = nsHtml5Portability::newCharArrayFromString(attributes->getValue(promptIndex));
|
||||
autoJArray<PRUnichar,int32_t> prompt = nsHtml5Portability::newCharArrayFromString(attributes->getValueNoBoundsCheck(promptIndex));
|
||||
appendCharacters(stack[currentPtr]->node, prompt, 0, prompt.length);
|
||||
} else {
|
||||
appendIsindexPrompt(stack[currentPtr]->node);
|
||||
|
@ -1147,11 +1147,11 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
|
|||
nsHtml5HtmlAttributes* inputAttributes = new nsHtml5HtmlAttributes(0);
|
||||
inputAttributes->addAttribute(nsHtml5AttributeName::ATTR_NAME, nsHtml5Portability::newStringFromLiteral("isindex"));
|
||||
for (int32_t i = 0; i < attributes->getLength(); i++) {
|
||||
nsHtml5AttributeName* attributeQName = attributes->getAttributeName(i);
|
||||
nsHtml5AttributeName* attributeQName = attributes->getAttributeNameNoBoundsCheck(i);
|
||||
if (nsHtml5AttributeName::ATTR_NAME == attributeQName || nsHtml5AttributeName::ATTR_PROMPT == attributeQName) {
|
||||
attributes->releaseValue(i);
|
||||
} else if (nsHtml5AttributeName::ATTR_ACTION != attributeQName) {
|
||||
inputAttributes->addAttribute(attributeQName, attributes->getValue(i));
|
||||
inputAttributes->addAttribute(attributeQName, attributes->getValueNoBoundsCheck(i));
|
||||
}
|
||||
}
|
||||
attributes->clearWithoutReleasingContents();
|
||||
|
|
|
@ -305,12 +305,17 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||
--i;
|
||||
// prefix doesn't need regetting. it is always null or a static atom
|
||||
// local name is never null
|
||||
nsCOMPtr<nsIAtom> localName = Reget(attributes->getLocalName(i));
|
||||
int32_t nsuri = attributes->getURI(i);
|
||||
nsCOMPtr<nsIAtom> localName =
|
||||
Reget(attributes->getLocalNameNoBoundsCheck(i));
|
||||
int32_t nsuri = attributes->getURINoBoundsCheck(i);
|
||||
if (!node->HasAttr(nsuri, localName)) {
|
||||
// prefix doesn't need regetting. it is always null or a static atom
|
||||
// local name is never null
|
||||
node->SetAttr(nsuri, localName, attributes->getPrefix(i), *(attributes->getValue(i)), true);
|
||||
node->SetAttr(nsuri,
|
||||
localName,
|
||||
attributes->getPrefixNoBoundsCheck(i),
|
||||
*(attributes->getValueNoBoundsCheck(i)),
|
||||
true);
|
||||
// XXX what to do with nsresult?
|
||||
}
|
||||
}
|
||||
|
@ -404,19 +409,26 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||
--i;
|
||||
// prefix doesn't need regetting. it is always null or a static atom
|
||||
// local name is never null
|
||||
nsCOMPtr<nsIAtom> localName = Reget(attributes->getLocalName(i));
|
||||
nsCOMPtr<nsIAtom> localName =
|
||||
Reget(attributes->getLocalNameNoBoundsCheck(i));
|
||||
if (ns == kNameSpaceID_XHTML &&
|
||||
nsHtml5Atoms::a == name &&
|
||||
nsHtml5Atoms::name == localName) {
|
||||
// This is an HTML5-incompliant Geckoism.
|
||||
// Remove when fixing bug 582361
|
||||
NS_ConvertUTF16toUTF8 cname(*(attributes->getValue(i)));
|
||||
NS_ConvertUTF16toUTF8 cname(*(attributes->getValueNoBoundsCheck(i)));
|
||||
NS_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting()));
|
||||
newContent->SetAttr(attributes->getURI(i), localName,
|
||||
attributes->getPrefix(i), uv, false);
|
||||
newContent->SetAttr(attributes->getURINoBoundsCheck(i),
|
||||
localName,
|
||||
attributes->getPrefixNoBoundsCheck(i),
|
||||
uv,
|
||||
false);
|
||||
} else {
|
||||
newContent->SetAttr(attributes->getURI(i), localName,
|
||||
attributes->getPrefix(i), *(attributes->getValue(i)), false);
|
||||
newContent->SetAttr(attributes->getURINoBoundsCheck(i),
|
||||
localName,
|
||||
attributes->getPrefixNoBoundsCheck(i),
|
||||
*(attributes->getValueNoBoundsCheck(i)),
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче