summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sax/source/tools/fastserializer.cxx43
1 files changed, 33 insertions, 10 deletions
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index 1a422ad8239a..70a359b1c5ee 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -199,6 +199,7 @@ namespace sax_fastparser {
default:
if (mbXescape)
{
+ char c1, c2, c3, c4;
// Escape characters not valid in XML 1.0 as
// _xHHHH_. A literal "_xHHHH_" has to be
// escaped as _x005F_xHHHH_ (effectively
@@ -209,22 +210,44 @@ namespace sax_fastparser {
if (c == '_' && i >= nNextXescape && i <= nLen - kXescapeLen &&
pStr[i+6] == '_' &&
((pStr[i+1] | 0x20) == 'x') &&
- isHexDigit( pStr[i+2] ) &&
- isHexDigit( pStr[i+3] ) &&
- isHexDigit( pStr[i+4] ) &&
- isHexDigit( pStr[i+5] ))
+ isHexDigit( c1 = pStr[i+2] ) &&
+ isHexDigit( c2 = pStr[i+3] ) &&
+ isHexDigit( c3 = pStr[i+4] ) &&
+ isHexDigit( c4 = pStr[i+5] ))
{
// OOXML has the odd habit to write some
// names using this that when re-saving
// should *not* be escaped, specifically
// _x0020_ for blanks in w:xpath values.
- if (strncmp( pStr+i+2, "0020", 4) != 0)
+ if (!(c1 == '0' && c2 == '0' && c3 == '2' && c4 == '0'))
{
- writeBytes( "_x005F_", kXescapeLen);
- // Remember this escapement so in
- // _xHHHH_xHHHH_ only the first '_' is
- // escaped.
- nNextXescape = i + kXescapeLen;
+ // When encountering "_x005F_xHHHH_"
+ // assume that is an already escaped
+ // sequence that was not unescaped and
+ // shall be written as is, to not end
+ // up with "_x005F_x005F_xHHHH_" and
+ // repeated..
+ if (c1 == '0' && c2 == '0' && c3 == '5' && (c4 | 0x20) == 'f' &&
+ i + kXescapeLen <= nLen - 6 &&
+ pStr[i+kXescapeLen+5] == '_' &&
+ ((pStr[i+kXescapeLen+0] | 0x20) == 'x') &&
+ isHexDigit( pStr[i+kXescapeLen+1] ) &&
+ isHexDigit( pStr[i+kXescapeLen+2] ) &&
+ isHexDigit( pStr[i+kXescapeLen+3] ) &&
+ isHexDigit( pStr[i+kXescapeLen+4] ))
+ {
+ writeBytes( &c, 1 );
+ // Remember this fake escapement.
+ nNextXescape = i + kXescapeLen + 6;
+ }
+ else
+ {
+ writeBytes( "_x005F_", kXescapeLen);
+ // Remember this escapement so in
+ // _xHHHH_xHHHH_ only the first '_'
+ // is escaped.
+ nNextXescape = i + kXescapeLen;
+ }
break;
}
}