From: znek Date: Thu, 15 Mar 2007 21:43:32 +0000 (+0000) Subject: properly decode attribute values before passing them as events X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2736da849e4784d7ee0663f1b9c8660724fc532;p=sope properly decode attribute values before passing them as events git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1456 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-xml/libxmlSAXDriver/ChangeLog b/sope-xml/libxmlSAXDriver/ChangeLog index 387c2f3d..77dead4b 100644 --- a/sope-xml/libxmlSAXDriver/ChangeLog +++ b/sope-xml/libxmlSAXDriver/ChangeLog @@ -1,3 +1,12 @@ +2007-03-15 Marcus Mueller + + * libxmlSAXDriver.m: properly decode #%i; values in attributes - + libxml2 doesn't decode them properly, but the driver is expected + to do so. While fixing this also refrained from using the global + uniqued string cache for these values (I guess the former is + correct for tags and attribute names, but using it for values + feels somewhat odd). (v4.7.25) + 2006-07-03 Helge Hess * v4.5.24 diff --git a/sope-xml/libxmlSAXDriver/Version b/sope-xml/libxmlSAXDriver/Version index d20c0852..270c14ca 100644 --- a/sope-xml/libxmlSAXDriver/Version +++ b/sope-xml/libxmlSAXDriver/Version @@ -1,3 +1,3 @@ # version -SUBMINOR_VERSION:=24 +SUBMINOR_VERSION:=25 diff --git a/sope-xml/libxmlSAXDriver/libxmlSAXDriver-Info.plist b/sope-xml/libxmlSAXDriver/libxmlSAXDriver-Info.plist index 1b0352a3..4b2b1c44 100644 --- a/sope-xml/libxmlSAXDriver/libxmlSAXDriver-Info.plist +++ b/sope-xml/libxmlSAXDriver/libxmlSAXDriver-Info.plist @@ -21,6 +21,6 @@ CFBundleSignature ???? CFBundleVersion - 4.5.17 + 4.7.25 diff --git a/sope-xml/libxmlSAXDriver/libxmlSAXDriver.m b/sope-xml/libxmlSAXDriver/libxmlSAXDriver.m index d12055fe..eed74969 100644 --- a/sope-xml/libxmlSAXDriver/libxmlSAXDriver.m +++ b/sope-xml/libxmlSAXDriver/libxmlSAXDriver.m @@ -79,6 +79,119 @@ static inline NSString *xmlCharsToString(const xmlChar *_s) { return s; } +static inline NSString *xmlCharsToDecodedString(const xmlChar *_s) { + NSString *s; + BOOL needsDecoding = NO; + unichar (*charAt)(id, SEL, unsigned int); + unsigned i, len, last; + + if (_s == NULL) return nil; + + if (NSStringClass == Nil) + NSStringClass = [NSString class]; + + s = [[NSStringClass alloc] initWithUTF8String:(const char *)_s]; + len = [s length]; + charAt = (void *)[s methodForSelector:@selector(characterAtIndex:)]; + + for (i = 0; i < len; i++) { + if (charAt(s, @selector(characterAtIndex:), i) == '&') { + needsDecoding = YES; + last = 0; + break; + } + } + if (needsDecoding) { + NSMutableString *ds; + + ds = [[NSMutableString alloc] initWithCapacity:len]; + for (; i < len; i++) { + if (charAt(s, @selector(characterAtIndex:), i) == '&') { + NSRange r; + + r = NSMakeRange(last, i - last); + [ds appendString:[s substringWithRange:r]]; + if (charAt(s, @selector(characterAtIndex:), i + 1) == '#') { + NSRange vr; + unichar c; + + r = NSMakeRange(i + 2, len - i - 2); + r = [s rangeOfString:@";" options:0 range:r]; + c = (unichar)charAt(s, @selector(characterAtIndex:), i + 2); + /* hex value? */ + if (c == 'x' || c == 'X') { + unsigned value; + + vr = NSMakeRange(i + 3, r.location - i - 3); + value = [[NSScanner scannerWithString:[s substringWithRange:vr]] + scanHexInt:&value]; + c = (unichar)value; + } + else { + vr = NSMakeRange(i + 2, r.location - i - 2); + c = (unichar)[[s substringWithRange:vr] intValue]; + } + [ds appendString:[NSString stringWithCharacters:&c length:1]]; + i = NSMaxRange(r); + last = i; + } + else { + if ((charAt(s, @selector(characterAtIndex:), i + 1) == 'a') && + (charAt(s, @selector(characterAtIndex:), i + 2) == 'm') && + (charAt(s, @selector(characterAtIndex:), i + 3) == 'p')) + { + [ds appendString:@"&"]; + i += 5; + } + else if ((charAt(s, @selector(characterAtIndex:), i + 1) == 'q') && + (charAt(s, @selector(characterAtIndex:), i + 2) == 'u') && + (charAt(s, @selector(characterAtIndex:), i + 3) == 'o') && + (charAt(s, @selector(characterAtIndex:), i + 4) == 't')) + { + [ds appendString:@"\""]; + i += 6; + } + else if ((charAt(s, @selector(characterAtIndex:), i + 1) == 'a') && + (charAt(s, @selector(characterAtIndex:), i + 2) == 'p') && + (charAt(s, @selector(characterAtIndex:), i + 3) == 'o') && + (charAt(s, @selector(characterAtIndex:), i + 4) == 's')) + { + [ds appendString:@"'"]; + i += 6; + } + else if ((charAt(s, @selector(characterAtIndex:), i + 1) == 'l') && + (charAt(s, @selector(characterAtIndex:), i + 2) == 't')) + { + [ds appendString:@"<"]; + i += 4; + } + else if ((charAt(s, @selector(characterAtIndex:), i + 1) == 'g') && + (charAt(s, @selector(characterAtIndex:), i + 2) == 't')) + { + [ds appendString:@">"]; + i += 4; + } + else { + NSRange r; + + r = NSMakeRange(i + 1, len - i - 1); + r = [s rangeOfString:@";" options:0 range:r]; + r = NSMakeRange(i, r.location - i); + [ds appendString:[s substringWithRange:r]]; + i = NSMaxRange(r); + } + last = i; + } + } + } + if (last != (len - 1)) + [ds appendString:[s substringFromIndex:last]]; + [s release]; + s = ds; + } + return s; +} + extern xmlParserCtxtPtr xmlCreateMemoryParserCtxt(char *buffer, int size); @implementation libxmlSAXDriver @@ -824,7 +937,7 @@ _startElement(libxmlSAXDriver *self, const xmlChar *name, const xmlChar **atts) } type = @"CDATA"; - value = xmlCharsToString(atts[i + 1]); + value = xmlCharsToDecodedString(atts[i + 1]); [self->attrs addAttribute:name uri:uri rawName:rawName