mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
Fix for XML plist parsing.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29066 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
26ec2df638
commit
3992cde903
2 changed files with 79 additions and 12 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2009-11-26 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSPropertyList.m: Revert last change, which broke XML
|
||||
generation by placing illegal character entities in the output.
|
||||
Fix menu position problem by adding missing code to unescape
|
||||
the \U escapes we put in the output when we read back in again.
|
||||
NB. should check that we use character entities for all legal
|
||||
characters and only use the escape mechanism for *really* illegal
|
||||
ones (such as the menu location key).
|
||||
|
||||
2009-11-26 Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||
|
||||
* Source/NSPropertyList.m (XString): Write out proper XML encoding
|
||||
|
|
|
@ -53,6 +53,13 @@
|
|||
|
||||
@class GSSloppyXMLParser;
|
||||
|
||||
#define inrange(ch,min,max) ((ch)>=(min) && (ch)<=(max))
|
||||
#define char2num(ch) \
|
||||
inrange(ch,'0','9') \
|
||||
? ((ch)-0x30) \
|
||||
: (inrange(ch,'a','f') \
|
||||
? ((ch)-0x57) : ((ch)-0x37))
|
||||
|
||||
/*
|
||||
* Cache classes.
|
||||
*/
|
||||
|
@ -102,6 +109,7 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
|||
namespaceURI: (NSString *)namespaceURI
|
||||
qualifiedName: (NSString *)qName;
|
||||
- (id) result;
|
||||
- (void) unescape;
|
||||
@end
|
||||
|
||||
@implementation GSXMLPListParser
|
||||
|
@ -230,6 +238,7 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
|||
}
|
||||
else if ([elementName isEqualToString: @"key"] == YES)
|
||||
{
|
||||
[self unescape];
|
||||
ASSIGNCOPY(key, value);
|
||||
[value setString: @""];
|
||||
return;
|
||||
|
@ -271,6 +280,7 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
|||
{
|
||||
id o;
|
||||
|
||||
[self unescape];
|
||||
if (opts == NSPropertyListMutableContainersAndLeaves)
|
||||
{
|
||||
o = [value mutableCopy];
|
||||
|
@ -343,6 +353,56 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
|||
return plist;
|
||||
}
|
||||
|
||||
- (void) unescape
|
||||
{
|
||||
id o;
|
||||
NSRange r;
|
||||
|
||||
/* Convert any \Uxxxx sequences to unicode characters.
|
||||
*/
|
||||
r = NSMakeRange(0, [value length]);
|
||||
while (r.length >= 6)
|
||||
{
|
||||
r = [value rangeOfString: @"\\U" options: NSLiteralSearch range: r];
|
||||
if (r.length == 2 && [value length] >= r.location + 6)
|
||||
{
|
||||
unichar c;
|
||||
unichar v;
|
||||
|
||||
c = [value characterAtIndex: r.location + 2];
|
||||
if (isxdigit(c))
|
||||
{
|
||||
v = char2num(c);
|
||||
c = [value characterAtIndex: r.location + 3];
|
||||
if (isxdigit(c))
|
||||
{
|
||||
v <<= 4;
|
||||
v |= char2num(c);
|
||||
c = [value characterAtIndex: r.location + 4];
|
||||
if (isxdigit(c))
|
||||
{
|
||||
v <<= 4;
|
||||
v |= char2num(c);
|
||||
c = [value characterAtIndex: r.location + 5];
|
||||
if (isxdigit(c))
|
||||
{
|
||||
v <<= 4;
|
||||
v |= char2num(c);
|
||||
o = [NSString alloc];
|
||||
o = [o initWithCharacters: &v length: 1];
|
||||
r.length += 4;
|
||||
[value replaceCharactersInRange: r withString: o];
|
||||
[o release];
|
||||
r.location++;
|
||||
r.length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r = NSMakeRange(NSMaxRange(r), [value length] - NSMaxRange(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
|
@ -511,13 +571,6 @@ static void setupQuotables(void)
|
|||
}
|
||||
}
|
||||
|
||||
#define inrange(ch,min,max) ((ch)>=(min) && (ch)<=(max))
|
||||
#define char2num(ch) \
|
||||
inrange(ch,'0','9') \
|
||||
? ((ch)-0x30) \
|
||||
: (inrange(ch,'a','f') \
|
||||
? ((ch)-0x57) : ((ch)-0x37))
|
||||
|
||||
typedef struct {
|
||||
const unsigned char *ptr;
|
||||
unsigned end;
|
||||
|
@ -1545,7 +1598,7 @@ XString(NSString* obj, NSMutableData *output)
|
|||
if ((c < 0x20 && (c != 0x09 && c != 0x0A && c != 0x0D))
|
||||
|| (c > 0xD7FF && c < 0xE000) || c > 0xFFFD)
|
||||
{
|
||||
len += 8;
|
||||
len += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1600,14 +1653,18 @@ XString(NSString* obj, NSMutableData *output)
|
|||
if ((c < 0x20 && (c != 0x09 && c != 0x0A && c != 0x0D))
|
||||
|| (c > 0xD7FF && c < 0xE000) || c > 0xFFFD)
|
||||
{
|
||||
map[wpos++] = '&';
|
||||
map[wpos++] = '#';
|
||||
map[wpos++] = 'x';
|
||||
/* We need to be able to encode characters in a
|
||||
* property list which are illegal in XML (even
|
||||
* when encoded as numeric entities with the
|
||||
* &#...; format. So we use the same \Uxxxx
|
||||
* format is in old style property lists.
|
||||
*/
|
||||
map[wpos++] = '\\';
|
||||
map[wpos++] = 'U';
|
||||
map[wpos++] = hexdigits[(c>>12) & 0xf];
|
||||
map[wpos++] = hexdigits[(c>>8) & 0xf];
|
||||
map[wpos++] = hexdigits[(c>>4) & 0xf];
|
||||
map[wpos++] = hexdigits[c & 0xf];
|
||||
map[wpos++] = ';';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue