[GB.XML]
* BUG: .XmlReader.Node.Attributes: Raise an error instead of segfault when an attribute does not exist * NEW: .XmlReader.Node.Attributes.Exist() is a new method to check if an attribute is present * BUG: XmlReader: Fix recognition of CDATA elements when their contents look like XML * BUG: XmlReader: Correctly detect ending sequence of CDATA and comment sections (reset the recognition state when the sequence is interrupted) git-svn-id: svn://localhost/gambas/trunk@8116 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
91518a2b72
commit
9b105f5f19
2 changed files with 50 additions and 14 deletions
|
@ -141,10 +141,31 @@ if(!THIS->foundNode->type == Node::ElementNode) return;
|
|||
|
||||
Attribute *attr = XMLElement_GetAttribute((Element*)(THIS->foundNode), STRING(name), LENGTH(name));
|
||||
|
||||
if (!attr)
|
||||
{
|
||||
GB.Error("No such attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
GB.ReturnNewString(attr->attrValue, attr->lenAttrValue);
|
||||
|
||||
END_METHOD
|
||||
|
||||
BEGIN_METHOD(CReaderNodeAttr_Exist, GB_STRING name)
|
||||
|
||||
if(!THIS->foundNode || THIS->state == READ_END_CUR_ELEMENT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!THIS->foundNode->type == Node::ElementNode) return;
|
||||
|
||||
Attribute *attr = XMLElement_GetAttribute((Element*)(THIS->foundNode), STRING(name), LENGTH(name));
|
||||
|
||||
GB.ReturnBoolean(!!attr);
|
||||
|
||||
END_METHOD
|
||||
|
||||
BEGIN_PROPERTY(CReaderNodeAttr_count)
|
||||
|
||||
if(!THIS->foundNode || THIS->state == READ_END_CUR_ELEMENT)
|
||||
|
@ -353,6 +374,7 @@ GB_DESC CReaderNodeAttributesDesc[] =
|
|||
|
||||
GB_METHOD("_get", "s", CReaderNodeAttr_get, "(Name)s"),
|
||||
GB_METHOD("_next", "s", CReaderNodeAttr_next, ""),
|
||||
GB_METHOD("Exist", "b", CReaderNodeAttr_Exist, "(Name)s"),
|
||||
GB_PROPERTY_READ("Count", "i", CReaderNodeAttr_count),
|
||||
GB_PROPERTY_READ("Name", "i", CReaderNodeAttr_name),
|
||||
GB_PROPERTY_READ("Value", "i", CReaderNodeAttr_value),
|
||||
|
|
|
@ -138,7 +138,21 @@ int Reader::ReadChar(char car)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(car == '<' && !inComment)//Début de tag
|
||||
/* [T. Boege, 02 Apr 2017]: Reset specialTagLevel, which tries to recognise a sequence
|
||||
* of characters, when this sequence is interrupted, so that e.g. <![CDATA[ab]x]>
|
||||
* does *not* finish the CDATA tag at ]x]>. We want a literal ]]>. */
|
||||
if (inCDATA)
|
||||
{
|
||||
if (specialTagLevel > CDATA_TAG_STARTCHAR_8 && car != ']' && car != '>')
|
||||
specialTagLevel = CDATA_TAG_STARTCHAR_8;
|
||||
}
|
||||
if (inComment)
|
||||
{
|
||||
if (specialTagLevel > COMMENT_TAG_STARTCHAR_3 && car != '-' && car != '-')
|
||||
specialTagLevel = COMMENT_TAG_STARTCHAR_3;
|
||||
}
|
||||
|
||||
if(car == '<' && !inComment && !inCDATA)//Début de tag
|
||||
{
|
||||
if(inTag)//Si on est déjà dans un tag
|
||||
{
|
||||
|
@ -166,7 +180,7 @@ int Reader::ReadChar(char car)
|
|||
return NODE_TEXT;
|
||||
}
|
||||
}
|
||||
else if(car == '>' && inTag && !inEndTag && !inComment)//Fin de tag (de nouvel élément)
|
||||
else if(car == '>' && inTag && !inEndTag && !inComment && !inCDATA)//Fin de tag (de nouvel élément)
|
||||
{
|
||||
DESTROYPARENT(foundNode);
|
||||
//UNREF(foundNode);
|
||||
|
@ -195,12 +209,12 @@ int Reader::ReadChar(char car)
|
|||
this->state = NODE_ELEMENT;
|
||||
return NODE_ELEMENT;
|
||||
}
|
||||
else if(isWhiteSpace(car) && inTag && inTagName && !inComment)// Fin de tagName
|
||||
else if(isWhiteSpace(car) && inTag && inTagName && !inComment && !inCDATA)// Fin de tagName
|
||||
{
|
||||
inTagName = false;
|
||||
XMLElement_RefreshPrefix((Element*)curNode);
|
||||
}
|
||||
else if(isNameStartChar(car) && inTag && !inTagName && !inEndTag && !inAttrVal && !inAttrName && !inComment)//Début de nom d'attribut
|
||||
else if(isNameStartChar(car) && inTag && !inTagName && !inEndTag && !inAttrVal && !inAttrName && !inComment && !inCDATA)//Début de nom d'attribut
|
||||
{
|
||||
if(attrName && attrVal)
|
||||
{
|
||||
|
@ -220,16 +234,16 @@ int Reader::ReadChar(char car)
|
|||
*attrName = car;
|
||||
lenAttrName = 1;
|
||||
}
|
||||
else if(car == '=' && inAttrName && !inComment)//Fin du nom d'attribut
|
||||
else if(car == '=' && inAttrName && !inComment && !inCDATA)//Fin du nom d'attribut
|
||||
{
|
||||
inAttrName = false;
|
||||
}
|
||||
else if((car == '\'' || car == '"') && inAttr && !inAttrVal && !inComment)//Début de valeur d'attribut
|
||||
else if((car == '\'' || car == '"') && inAttr && !inAttrVal && !inComment && !inCDATA)//Début de valeur d'attribut
|
||||
{
|
||||
inAttrVal = true;
|
||||
attrVal = 0;
|
||||
}
|
||||
else if((car == '\'' || car == '"') && inAttr && inAttrVal && !inComment)//Fin de valeur d'attribut
|
||||
else if((car == '\'' || car == '"') && inAttr && inAttrVal && !inComment && !inCDATA)//Fin de valeur d'attribut
|
||||
{
|
||||
XMLElement_AddAttribute(((Element*)curNode), attrName, lenAttrName,
|
||||
attrVal, lenAttrVal);
|
||||
|
@ -240,7 +254,7 @@ int Reader::ReadChar(char car)
|
|||
this->state = READ_ATTRIBUTE;
|
||||
return READ_ATTRIBUTE;
|
||||
}
|
||||
else if(car == '/' && inTag && !inAttrVal && !inComment)//Self-closed element
|
||||
else if(car == '/' && inTag && !inAttrVal && !inComment && !inCDATA)//Self-closed element
|
||||
{
|
||||
inTag = false;
|
||||
inTagName = false;
|
||||
|
@ -256,13 +270,13 @@ int Reader::ReadChar(char car)
|
|||
depth++;
|
||||
return NODE_ELEMENT;
|
||||
}
|
||||
else if(car == '/' && inNewTag && !inComment)//C'est un tag de fin
|
||||
else if(car == '/' && inNewTag && !inComment && !inCDATA)//C'est un tag de fin
|
||||
{
|
||||
inEndTag = true;
|
||||
inNewTag = false;
|
||||
inTag = true;
|
||||
}
|
||||
else if(car == '>' && inEndTag && !inComment)//La fin d'un tag de fin
|
||||
else if(car == '>' && inEndTag && !inComment && !inCDATA)//La fin d'un tag de fin
|
||||
{
|
||||
inTag = false;
|
||||
inEndTag = false;
|
||||
|
@ -350,7 +364,7 @@ int Reader::ReadChar(char car)
|
|||
return NODE_CDATA;
|
||||
}
|
||||
//Caractère "-" de début de commentaire
|
||||
else if(inCommentTag && car == '-' && specialTagLevel >= COMMENT_TAG_STARTCHAR_1 && specialTagLevel < COMMENT_TAG_STARTCHAR_3 && !inComment)
|
||||
else if(inCommentTag && car == '-' && specialTagLevel >= COMMENT_TAG_STARTCHAR_1 && specialTagLevel < COMMENT_TAG_STARTCHAR_3 && !inComment && !inCDATA)
|
||||
{
|
||||
++specialTagLevel;
|
||||
if (specialTagLevel == COMMENT_TAG_STARTCHAR_3)//Le tag <!-- est complet, on crée un nouveau node
|
||||
|
@ -396,17 +410,17 @@ int Reader::ReadChar(char car)
|
|||
return NODE_COMMENT;
|
||||
}
|
||||
//Début de prologue XML
|
||||
else if(car == '?' && inNewTag && !inComment)
|
||||
else if(car == '?' && inNewTag && !inComment && !inCDATA)
|
||||
{
|
||||
inXMLProlog = true;
|
||||
inNewTag = false;
|
||||
inTag = false;
|
||||
}
|
||||
else if(car == '?' && inXMLProlog && !inComment)
|
||||
else if(car == '?' && inXMLProlog && !inComment && !inCDATA)
|
||||
{
|
||||
specialTagLevel = PROLOG_TAG_ENDCHAR;
|
||||
}
|
||||
else if(car == '>' && inXMLProlog && specialTagLevel == PROLOG_TAG_ENDCHAR && !inComment)
|
||||
else if(car == '>' && inXMLProlog && specialTagLevel == PROLOG_TAG_ENDCHAR && !inComment && !inCDATA)
|
||||
{
|
||||
specialTagLevel = 0;
|
||||
inXMLProlog = 0;
|
||||
|
|
Loading…
Reference in a new issue