summaryrefslogtreecommitdiffstats
path: root/qtools/qxml.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qtools/qxml.cpp')
-rw-r--r--qtools/qxml.cpp405
1 files changed, 222 insertions, 183 deletions
diff --git a/qtools/qxml.cpp b/qtools/qxml.cpp
index d171828..11a9b01 100644
--- a/qtools/qxml.cpp
+++ b/qtools/qxml.cpp
@@ -35,6 +35,7 @@
**
**********************************************************************/
+#define QT_XML_CPP
#include "qxml.h"
#include "qtextcodec.h"
#include "qbuffer.h"
@@ -80,7 +81,7 @@
#define XMLERR_EDECLORSDDECLEXPECTED "EDecl or SDDecl expected while reading the XML declaration"
#define XMLERR_SDDECLEXPECTED "SDDecl expected while reading the XML declaration"
#define XMLERR_WRONGVALUEFORSDECL "wrong value for standalone declaration"
-#define XMLERR_UNPARSEDENTITYREFERENCE "unparsed entity reference"
+#define XMLERR_UNPARSEDENTITYREFERENCE "unparsed entity reference in wrong context"
#define XMLERR_INTERNALGENERALENTITYINDTD "internal general entity reference not allowed in DTD"
#define XMLERR_EXTERNALGENERALENTITYINDTD "external parsed general entity reference not allowed in DTD"
#define XMLERR_EXTERNALGENERALENTITYINAV "external parsed general entity reference not allowed in attribute value"
@@ -2733,13 +2734,14 @@ bool QXmlSimpleReader::parseContent()
next();
break;
case Ref:
- // reference may be CharData; so clear string to be safe
if ( !charDataRead) {
- charDataRead = TRUE;
+ // reference may be CharData; so clear string to be safe
stringClear();
+ parseOk = parseReference( charDataRead, InContent );
+ } else {
+ bool tmp;
+ parseOk = parseReference( tmp, InContent );
}
- // parse reference
- parseOk = parseReference( charDataRead, InContent );
break;
case Lt:
// call the handler for CharData
@@ -2977,6 +2979,12 @@ bool QXmlSimpleReader::parseMisc()
d->error = XMLERR_ERRORPARSINGPI;
goto parseError;
}
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
return TRUE;
case Comment2:
if ( !parseOk ) {
@@ -3241,8 +3249,8 @@ parseError:
bool QXmlSimpleReader::parseDoctype()
{
// some init-stuff
- d->systemId = "";
- d->publicId = "";
+ d->systemId = QString::null;
+ d->publicId = QString::null;
const signed char Init = 0;
const signed char Doctype = 1; // read the doctype
@@ -3420,8 +3428,8 @@ parseError:
bool QXmlSimpleReader::parseExternalID( bool allowPublicID )
{
// some init-stuff
- d->systemId = "";
- d->publicId = "";
+ d->systemId = QString::null;
+ d->publicId = QString::null;
const signed char Init = 0;
const signed char Sys = 1; // parse 'SYSTEM'
@@ -3687,6 +3695,12 @@ bool QXmlSimpleReader::parseMarkupdecl()
d->error = XMLERR_ERRORPARSINGPI;
goto parseError;
}
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
return TRUE;
case Dash:
if ( !parseOk ) {
@@ -3812,13 +3826,13 @@ bool QXmlSimpleReader::parsePEReference( EntityRecognitionContext context )
}
}
} else {
- if ( context == InEntityValue ) {
+ if ( context == InEntityValue ) {
// Included in literal
xmlRef = d->parameterEntities.find( ref() )
.data().replace( QRegExp("\""), """ ).replace( QRegExp("'"), "'" )
+ xmlRef;
} else if ( context == InDTD ) {
- // Included as PE ### correct???
+ // Included as PE
xmlRef = QString(" ") +
d->parameterEntities.find( ref() ).data() +
QString(" ") + xmlRef;
@@ -4896,6 +4910,7 @@ bool QXmlSimpleReader::parseEntityDecl()
const signed char PEVal = 15; // parse entity value
const signed char PEEID = 16; // parse ExternalID
const signed char WsE = 17; // white space read
+ const signed char EDDone = 19; // done, but also report an external, unparsed entity decl
const signed char Done = 18;
const signed char InpWs = 0; // white space
@@ -4914,8 +4929,8 @@ bool QXmlSimpleReader::parseEntityDecl()
{ Ws2, -1, -1, -1, -1, -1 }, // Name
{ -1, -1, EValue, -1, -1, ExtID }, // Ws2
{ WsE, -1, -1, Done, -1, -1 }, // EValue
- { Ws3, -1, -1, Done, -1, -1 }, // ExtID
- { -1, -1, -1, Done, Ndata, -1 }, // Ws3
+ { Ws3, -1, -1, EDDone,-1, -1 }, // ExtID
+ { -1, -1, -1, EDDone,Ndata, -1 }, // Ws3
{ Ws4, -1, -1, -1, -1, -1 }, // Ndata
{ -1, -1, -1, -1, NNam, NNam }, // Ws4
{ WsE, -1, -1, Done, -1, -1 }, // NNam
@@ -5008,6 +5023,9 @@ bool QXmlSimpleReader::parseEntityDecl()
case WsE:
eat_ws();
break;
+ case EDDone:
+ next();
+ break;
case Done:
next();
break;
@@ -5031,8 +5049,7 @@ bool QXmlSimpleReader::parseEntityDecl()
d->error = XMLERR_ERRORPARSINGENTITYVALUE;
goto parseError;
}
- if ( d->entities.find( name() ) == d->entities.end() &&
- d->externEntities.find( name() ) == d->externEntities.end() ) {
+ if ( !entityExist( name() ) ) {
d->entities.insert( name(), string() );
if ( declHnd ) {
if ( !declHnd->internalEntityDecl( name(), string() ) ) {
@@ -5047,16 +5064,6 @@ bool QXmlSimpleReader::parseEntityDecl()
d->error = XMLERR_ERRORPARSINGEXTERNALID;
goto parseError;
}
- if ( d->entities.find( name() ) == d->entities.end() &&
- d->externEntities.find( name() ) == d->externEntities.end() ) {
- d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, "" ) );
- if ( declHnd ) {
- if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
- d->error = declHnd->errorString();
- goto parseError;
- }
- }
- }
break;
case Ndata:
if ( !parseOk ) {
@@ -5069,11 +5076,10 @@ bool QXmlSimpleReader::parseEntityDecl()
d->error = XMLERR_ERRORPARSINGNAME;
goto parseError;
}
- if ( d->entities.find( name() ) == d->entities.end() &&
- d->externEntities.find( name() ) == d->externEntities.end() ) {
+ if ( !entityExist( name() ) ) {
d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, ref() ) );
- if ( declHnd ) {
- if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
+ if ( dtdHnd ) {
+ if ( !dtdHnd->unparsedEntityDecl( name(), d->publicId, d->systemId, ref() ) ) {
d->error = declHnd->errorString();
goto parseError;
}
@@ -5091,8 +5097,7 @@ bool QXmlSimpleReader::parseEntityDecl()
d->error = XMLERR_ERRORPARSINGENTITYVALUE;
goto parseError;
}
- if ( d->parameterEntities.find( name() ) == d->parameterEntities.end() &&
- d->externParameterEntities.find( name() ) == d->externParameterEntities.end() ) {
+ if ( !entityExist( name() ) ) {
d->parameterEntities.insert( name(), string() );
if ( declHnd ) {
if ( !declHnd->internalEntityDecl( QString("%")+name(), string() ) ) {
@@ -5107,8 +5112,7 @@ bool QXmlSimpleReader::parseEntityDecl()
d->error = XMLERR_ERRORPARSINGEXTERNALID;
goto parseError;
}
- if ( d->parameterEntities.find( name() ) == d->parameterEntities.end() &&
- d->externParameterEntities.find( name() ) == d->externParameterEntities.end() ) {
+ if ( !entityExist( name() ) ) {
d->externParameterEntities.insert( name(), QXmlSimpleReaderPrivate::ExternParameterEntity( d->publicId, d->systemId ) );
if ( declHnd ) {
if ( !declHnd->externalEntityDecl( QString("%")+name(), d->publicId, d->systemId ) ) {
@@ -5118,6 +5122,17 @@ bool QXmlSimpleReader::parseEntityDecl()
}
}
break;
+ case EDDone:
+ if ( !entityExist( name() ) ) {
+ d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, QString::null ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ return TRUE;
case Done:
return TRUE;
case -1:
@@ -5741,154 +5756,8 @@ bool QXmlSimpleReader::parseReference( bool &charDataRead, EntityRecognitionCont
next();
break;
case DoneN:
- if ( ref() == "amp" ) {
- if ( context == InEntityValue ) {
- // Bypassed
- stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' );
- } else {
- // Included or Included in literal
- stringAddC( '&' );
- }
- charDataRead = TRUE;
- } else if ( ref() == "lt" ) {
- if ( context == InEntityValue ) {
- // Bypassed
- stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' );
- } else {
- // Included or Included in literal
- stringAddC( '<' );
- }
- charDataRead = TRUE;
- } else if ( ref() == "gt" ) {
- if ( context == InEntityValue ) {
- // Bypassed
- stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' );
- } else {
- // Included or Included in literal
- stringAddC( '>' );
- }
- charDataRead = TRUE;
- } else if ( ref() == "apos" ) {
- if ( context == InEntityValue ) {
- // Bypassed
- stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' );
- } else {
- // Included or Included in literal
- stringAddC( '\'' );
- }
- charDataRead = TRUE;
- } else if ( ref() == "quot" ) {
- if ( context == InEntityValue ) {
- // Bypassed
- stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' );
- } else {
- // Included or Included in literal
- stringAddC( '"' );
- }
- charDataRead = TRUE;
- } else {
- QMap<QString,QString>::Iterator it;
- it = d->entities.find( ref() );
- if ( it != d->entities.end() ) {
- // "Internal General"
- switch ( context ) {
- case InContent:
- // Included
- xmlRef = it.data() + xmlRef;
- charDataRead = FALSE;
- break;
- case InAttributeValue:
- // Included in literal
- xmlRef = it.data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
- + xmlRef;
- charDataRead = FALSE;
- break;
- case InEntityValue:
- {
- // Bypassed
- stringAddC( '&' );
- for ( int i=0; i<(int)ref().length(); i++ ) {
- stringAddC( ref()[i] );
- }
- stringAddC( ';');
- charDataRead = TRUE;
- }
- break;
- case InDTD:
- // Forbidden
- d->error = XMLERR_INTERNALGENERALENTITYINDTD;
- charDataRead = FALSE;
- break;
- }
- } else {
- QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
- itExtern = d->externEntities.find( ref() );
- if ( itExtern != d->externEntities.end() ) {
- // "External Parsed General"
- switch ( context ) {
- case InContent:
- // Included if validating
- if ( contentHnd ) {
- if ( !contentHnd->skippedEntity( ref() ) ) {
- d->error = contentHnd->errorString();
- goto parseError;
- }
- }
- charDataRead = FALSE;
- break;
- case InAttributeValue:
- // Forbidden
- d->error = XMLERR_EXTERNALGENERALENTITYINAV;
- charDataRead = FALSE;
- break;
- case InEntityValue:
- {
- // Bypassed
- stringAddC( '&' );
- for ( int i=0; i<(int)ref().length(); i++ ) {
- stringAddC( ref()[i] );
- }
- stringAddC( ';');
- charDataRead = TRUE;
- }
- break;
- case InDTD:
- // Forbidden
- d->error = XMLERR_EXTERNALGENERALENTITYINDTD;
- charDataRead = FALSE;
- break;
- }
- } else {
- // "Unparsed" ### or is the definition of unparsed entities different?
- if ( context == InEntityValue ) {
- // Bypassed
- // (this does not conform with the table 4.4 of the XML specification;
- // on the other hand: in this case it is not really an unparsed entity)
- stringAddC( '&' );
- for ( int i=0; i<(int)ref().length(); i++ ) {
- stringAddC( ref()[i] );
- }
- stringAddC( ';');
- charDataRead = TRUE;
- } else {
-#if 0
- // Forbidden
- d->error = XMLERR_UNPARSEDENTITYREFERENCE;
- goto parseError;
- charDataRead = FALSE;
-#else
- // ### skip it???
- if ( contentHnd ) {
- if ( !contentHnd->skippedEntity( ref() ) ) {
- d->error = contentHnd->errorString();
- goto parseError;
- }
- }
-#endif
- }
- }
- }
- }
+ if ( !processReference( charDataRead, context ) )
+ goto parseError;
next();
break;
}
@@ -5916,6 +5785,162 @@ parseError:
}
/*!
+ Helper function for parseReference()
+*/
+bool QXmlSimpleReader::processReference( bool &charDataRead, EntityRecognitionContext context )
+{
+ QString reference = ref();
+ if ( reference == "amp" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '&' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "lt" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '<' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "gt" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '>' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "apos" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '\'' );
+ }
+ charDataRead = TRUE;
+ } else if ( reference == "quot" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '"' );
+ }
+ charDataRead = TRUE;
+ } else {
+ QMap<QString,QString>::Iterator it;
+ it = d->entities.find( reference );
+ if ( it != d->entities.end() ) {
+ // "Internal General"
+ switch ( context ) {
+ case InContent:
+ // Included
+ xmlRef = it.data() + xmlRef;
+ charDataRead = FALSE;
+ break;
+ case InAttributeValue:
+ // Included in literal
+ xmlRef = it.data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
+ + xmlRef;
+ charDataRead = FALSE;
+ break;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->error = XMLERR_INTERNALGENERALENTITYINDTD;
+ charDataRead = FALSE;
+ break;
+ }
+ } else {
+ QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
+ itExtern = d->externEntities.find( reference );
+ if ( itExtern == d->externEntities.end() ) {
+ // entity not declared
+ // ### check this case for conformance
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ } else {
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( reference ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE; // error
+ }
+ }
+ }
+ } else if ( (*itExtern).notation.isNull() ) {
+ // "External Parsed General"
+ switch ( context ) {
+ case InContent:
+ // Included if validating
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( reference ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE; // error
+ }
+ }
+ charDataRead = FALSE;
+ break;
+ case InAttributeValue:
+ // Forbidden
+ d->error = XMLERR_EXTERNALGENERALENTITYINAV;
+ charDataRead = FALSE;
+ break;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->error = XMLERR_EXTERNALGENERALENTITYINDTD;
+ charDataRead = FALSE;
+ break;
+ }
+ } else {
+ // "Unparsed"
+ // ### notify for "Occurs as Attribute Value" missing (but this is no refence, anyway)
+ // Forbidden
+ d->error = XMLERR_UNPARSEDENTITYREFERENCE;
+ charDataRead = FALSE;
+ return FALSE; // error
+ }
+ }
+ }
+ return TRUE; // no error
+}
+
+
+/*!
Parse over a simple string.
After the string was successfully parsed, the head is on the first
@@ -5970,8 +5995,8 @@ parseError:
}
-/*
- Init the data values.
+/*!
+ Inits the data values.
*/
void QXmlSimpleReader::init( const QXmlInputSource& i )
{
@@ -5998,6 +6023,20 @@ void QXmlSimpleReader::init( const QXmlInputSource& i )
d->error = XMLERR_OK;
}
+/*!
+ Returns TRUE if a entity with the name \a e exists,
+ otherwise returns FALSE.
+*/
+bool QXmlSimpleReader::entityExist( const QString& e ) const
+{
+ if ( d->parameterEntities.find(e) == d->parameterEntities.end() &&
+ d->externParameterEntities.find(e) == d->externParameterEntities.end() ) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
void QXmlSimpleReader::reportParseError()
{
if ( errorHnd )