Bug 792790 - Introduce NoBoundsCheck variants of accessors on nsHtml5HtmlAttributes; Make operator= in jArray nullptr-aware. r=smaug.

This commit is contained in:
Henri Sivonen 2012-10-01 11:49:01 +03:00
Родитель 4649363c2e
Коммит b70e7be378
8 изменённых файлов: 187 добавлений и 116 удалений

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

@ -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);
}
}