]> err.no Git - sope/commitdiff
properly decode attribute values before passing them as events
authorznek <znek@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 15 Mar 2007 21:43:32 +0000 (21:43 +0000)
committerznek <znek@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 15 Mar 2007 21:43:32 +0000 (21:43 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1456 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-xml/libxmlSAXDriver/ChangeLog
sope-xml/libxmlSAXDriver/Version
sope-xml/libxmlSAXDriver/libxmlSAXDriver-Info.plist
sope-xml/libxmlSAXDriver/libxmlSAXDriver.m

index 387c2f3d435d60008d5bf93a71dfa5828cd9db4b..77dead4b4684ab6a303db89d680710dcee82a089 100644 (file)
@@ -1,3 +1,12 @@
+2007-03-15  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * 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  <helge.hess@opengroupware.org>
 
        * v4.5.24
index d20c0852da0d904e3c8b08e21e15baf29e07e01b..270c14ca3f2859758b1a28b8a7e97c7ba6595ccc 100644 (file)
@@ -1,3 +1,3 @@
 # version
 
-SUBMINOR_VERSION:=24
+SUBMINOR_VERSION:=25
index 1b0352a37d11e50ff7698c44f3cc43f77c62b67d..4b2b1c44ac679a62e40dbd9029fb6534231d0aa1 100644 (file)
@@ -21,6 +21,6 @@
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>4.5.17</string>
+       <string>4.7.25</string>
 </dict>
 </plist>
index d12055fee3cfa3daeda8cacdd42d02618d33a08b..eed749695563d3fe513717aafc6d594cd5cf9697 100644 (file)
@@ -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