Skip to content

Commit 30dee1e

Browse files
authored
Merge pull request #1021 from Malcohol/Malcohol/optionalAposHandling
Optional Apos escaping
2 parents a93163d + f87d0e3 commit 30dee1e

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

tinyxml2.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,7 +2577,7 @@ void XMLDocument::PopDepth()
25772577
--_parsingDepth;
25782578
}
25792579

2580-
XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
2580+
XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth, EscapeAposCharsInAttributes aposInAttributes ) :
25812581
_elementJustOpened( false ),
25822582
_stack(),
25832583
_firstElement( true ),
@@ -2594,9 +2594,11 @@ XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
25942594
}
25952595
for( int i=0; i<NUM_ENTITIES; ++i ) {
25962596
const char entityValue = entities[i].value;
2597-
const unsigned char flagIndex = static_cast<unsigned char>(entityValue);
2598-
TIXMLASSERT( flagIndex < ENTITY_RANGE );
2599-
_entityFlag[flagIndex] = true;
2597+
if ((aposInAttributes == ESCAPE_APOS_CHARS_IN_ATTRIBUTES) || (entityValue != SINGLE_QUOTE)) {
2598+
const unsigned char flagIndex = static_cast<unsigned char>(entityValue);
2599+
TIXMLASSERT( flagIndex < ENTITY_RANGE );
2600+
_entityFlag[flagIndex] = true;
2601+
}
26002602
}
26012603
_restrictedEntityFlag[static_cast<unsigned char>('&')] = true;
26022604
_restrictedEntityFlag[static_cast<unsigned char>('<')] = true;

tinyxml2.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2239,13 +2239,18 @@ class TINYXML2_LIB XMLConstHandle
22392239
class TINYXML2_LIB XMLPrinter : public XMLVisitor
22402240
{
22412241
public:
2242+
enum EscapeAposCharsInAttributes {
2243+
ESCAPE_APOS_CHARS_IN_ATTRIBUTES,
2244+
DONT_ESCAPE_APOS_CHARS_IN_ATTRIBUTES
2245+
};
2246+
22422247
/** Construct the printer. If the FILE* is specified,
22432248
this will print to the FILE. Else it will print
22442249
to memory, and the result is available in CStr().
22452250
If 'compact' is set to true, then output is created
22462251
with only required whitespace and newlines.
22472252
*/
2248-
XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
2253+
XMLPrinter( FILE* file=0, bool compact = false, int depth = 0, EscapeAposCharsInAttributes aposInAttributes = ESCAPE_APOS_CHARS_IN_ATTRIBUTES );
22492254
virtual ~XMLPrinter() {}
22502255

22512256
/** If streaming, write the BOM and declaration. */

xmltest.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2695,6 +2695,41 @@ int main( int argc, const char ** argv )
26952695
XMLTest("Test attribute encode with a Hex value", value5, "!"); // hex value in unicode value
26962696
}
26972697

2698+
// ---------- XMLPrinter Apos Escaping ------
2699+
{
2700+
const char* testText = "text containing a ' character";
2701+
XMLDocument doc;
2702+
XMLElement* element = doc.NewElement( "element" );
2703+
doc.InsertEndChild( element );
2704+
element->SetAttribute( "attrib", testText );
2705+
{
2706+
XMLPrinter defaultPrinter;
2707+
doc.Print( &defaultPrinter );
2708+
const char* defaultOutput = defaultPrinter.CStr();
2709+
const bool foundTextWithUnescapedApos = (strstr(defaultOutput, testText) != nullptr);
2710+
XMLTest("Default XMLPrinter should escape ' characters", false, foundTextWithUnescapedApos);
2711+
{
2712+
XMLDocument parsingDoc;
2713+
parsingDoc.Parse(defaultOutput);
2714+
const XMLAttribute* attrib = parsingDoc.FirstChildElement("element")->FindAttribute("attrib");
2715+
XMLTest("Default XMLPrinter should output parsable xml", testText, attrib->Value(), true);
2716+
}
2717+
}
2718+
{
2719+
XMLPrinter customPrinter(0, false, 0, XMLPrinter::DONT_ESCAPE_APOS_CHARS_IN_ATTRIBUTES);
2720+
doc.Print( &customPrinter );
2721+
const char* customOutput = customPrinter.CStr();
2722+
const bool foundTextWithUnescapedApos = (strstr(customOutput, testText) != nullptr);
2723+
XMLTest("Custom XMLPrinter should not escape ' characters", true, foundTextWithUnescapedApos);
2724+
{
2725+
XMLDocument parsingDoc;
2726+
parsingDoc.Parse(customOutput);
2727+
const XMLAttribute* attrib = parsingDoc.FirstChildElement("element")->FindAttribute("attrib");
2728+
XMLTest("Custom XMLPrinter should output parsable xml", testText, attrib->Value(), true);
2729+
}
2730+
}
2731+
}
2732+
26982733
// ----------- Performance tracking --------------
26992734
{
27002735
#if defined( _MSC_VER )

0 commit comments

Comments
 (0)