Package: libgnustep-base1.19 Version: > 1.19.1
When loading an XML Property List (plist) which contains leading or trailing whitespace in a string property, or whitespace surrounding an XML entity, this whitespace is incorrectly stripped. eg. <string> A & B </string> -> "A&B" This bug specifically affects the game Oolite on systems with these faulty versions of libgnustep-base. Oolite is packaged and shipped with Debian. This bug has been fixed by GNUstep in their trunk revision #30454 and they will backport the fix to the 1.20 version of gnustep-base. They have indicated they will not backport the fix to 1.19.x See: https://savannah.gnu.org/bugs/index.php?29955 The bug has also been raised for Ubuntu: See: https://bugs.launchpad.net/ubuntu/+source/gnustep-base/+bug/585179 Please find attached a backported patch for gnustep-base-1.19.3. This patch has been used to build PPA versions of libgnustep-base1.19 for Ubuntu Lucid and Ubuntu Maverick. See: https://launchpad.net/~3-launchpad-micha-michaelwerle-com/+archive/ppa Please also find attached a test program (supplied by Jens Ayton) which illustrates this issue. Specifically, Tests #1, #2, and #6 are affected. Many thanks, - Micha.
diff -u -r gnustep-base-1.19.3.orig/Source/NSPropertyList.m gnustep-base-1.19.3/Source/NSPropertyList.m --- gnustep-base-1.19.3.orig/Source/NSPropertyList.m 2009-08-04 09:08:52.000000000 +0100 +++ gnustep-base-1.19.3/Source/NSPropertyList.m 2010-05-29 20:20:02.733659340 +0100 @@ -81,6 +81,7 @@ NSString *key; BOOL inArray; BOOL inDictionary; + BOOL inString; BOOL parsed; BOOL success; id plist; @@ -129,10 +130,15 @@ } - (void) parser: (NSXMLParser *)parser - foundCharacters: (NSString *)string +foundCharacters: (NSString *)string { - string = [string stringByTrimmingSpaces]; - if ([string length] > 0) + [value appendString: string]; +} + +- (void) parser: (NSXMLParser *)parser +foundIgnorableWhitespace: (NSString *)string +{ + if (YES == inString) { [value appendString: string]; } @@ -176,6 +182,10 @@ inArray = YES; inDictionary = NO; } + else if ([elementName isEqualToString: @"string"] == YES) + { + inString = YES; + } } - (void) parser: (NSXMLParser *)parser @@ -185,11 +195,12 @@ { BOOL inContainer = NO; + inString = NO; if ([elementName isEqualToString: @"dict"] == YES) { inContainer = YES; } - if ([elementName isEqualToString: @"array"] == YES) + else if ([elementName isEqualToString: @"array"] == YES) { inContainer = YES; } diff -u -r gnustep-base-1.19.3.orig/Source/NSXMLParser.m gnustep-base-1.19.3/Source/NSXMLParser.m --- gnustep-base-1.19.3.orig/Source/NSXMLParser.m 2009-08-04 08:47:58.000000000 +0100 +++ gnustep-base-1.19.3/Source/NSXMLParser.m 2010-05-29 20:16:10.553667187 +0100 @@ -620,6 +620,8 @@ int line; // current line (counts from 0) int column; // current column (counts from 0) BOOL abort; // abort parse loop + BOOL ignorable; // whitespace is ignorable + BOOL whitespace; // had only whitespace in current data BOOL shouldProcessNamespaces; BOOL shouldReportNamespacePrefixes; BOOL shouldResolveExternalEntities; @@ -631,6 +633,7 @@ IMP foundCDATA; IMP foundCharacters; IMP foundComment; + IMP foundIgnorable; } NSXMLParserIvars; @@ -641,6 +644,7 @@ static SEL foundCDATASel; static SEL foundCharactersSel; static SEL foundCommentSel; +static SEL foundIgnorableSel; @implementation SloppyXMLParser @@ -674,6 +678,8 @@ = @selector(parser:foundCharacters:); foundCommentSel = @selector(parser:foundComment:); + foundIgnorableSel + = @selector(parser:foundIgnorableWhitespace:); } } @@ -813,6 +819,16 @@ { this->foundComment = 0; } + + if ([_del respondsToSelector: foundIgnorableSel]) + { + this->foundIgnorable + = [_del methodForSelector: foundIgnorableSel]; + } + else + { + this->foundIgnorable = 0; + } } } @@ -1220,6 +1236,10 @@ return [self _parseError: @"missing <?xml > preamble" code: NSXMLParserDocumentStartError]; } + /* Start by accumulating ignorable whitespace. + */ + this->ignorable = YES; + this->whitespace = YES; c = cget(); // get first character while (!this->abort) { @@ -1237,26 +1257,55 @@ this->column = 0; break; + case '<': + /* Whitespace immediately before an element is always ignorable. + */ + this->ignorable = YES; /* Fall through to push out data */ case EOF: - case '<': case '&': { /* push out any characters that have been collected so far */ if (this->cp - vp > 1) { - /* check for whitespace only - might set/reset - * a flag to indicate so - */ - if (this->foundCharacters != 0) - { - NSString *s; + const unsigned char *p; + NSString *s; - s = NewUTF8STR(vp, this->cp - vp - 1); + p = this->cp - 1; + if (YES == this->ignorable) + { + if (YES == this->whitespace) + { + p = vp; // all whitespace + } + else + { + /* step through trailing whitespace (if any) + */ + while (p > vp && isspace(p[-1])) + { + p--; + } + } + } + if (p - vp > 0 && this->foundCharacters != 0) + { + /* Process initial data as characters + */ + s = NewUTF8STR(vp, p - vp); (*this->foundCharacters)(_del, foundCharactersSel, self, s); [s release]; } + if (p < this->cp - 1 && this->foundIgnorable != 0) + { + /* Process data as ignorable whitespace + */ + s = NewUTF8STR(p, this->cp - p - 1); + (*this->foundIgnorable)(_del, + foundIgnorableSel, self, s); + [s release]; + } vp = this->cp; } } @@ -1265,6 +1314,30 @@ switch(c) { default: + if (YES == this->whitespace && !isspace(c)) + { + if (YES == this->ignorable && this->cp - vp > 1) + { + /* We have accumulated ignorable whitespace ... + * push it out. + */ + if (this->foundIgnorable != 0) + { + NSString *s; + + s = NewUTF8STR(vp, this->cp - vp - 1); + (*this->foundIgnorable)(_del, + foundIgnorableSel, self, s); + [s release]; + } + vp = this->cp - 1; + } + /* We have read non-space data, so whitespace is no longer + * ignorable, and the buffer no loinger contains only space. + */ + this->ignorable = NO; + this->whitespace = NO; + } c = cget(); // just collect until we push out (again) continue; @@ -1306,6 +1379,12 @@ { NSString *entity; + /* After any entity, whitespace is no longer ignorable, but + * we will have an empty buffer to accumulate it. + */ + this->ignorable = NO; + this->whitespace = YES; + if ([self _parseEntity: &entity] == NO) { return [self _parseError: @"empty entity name" @@ -1329,6 +1408,12 @@ NSString *arg; const unsigned char *tp = this->cp; // tag pointer + /* After processing a tag, whitespace will be ignorable and + * we can start accumulating it in our buffer. + */ + this->ignorable = YES; + this->whitespace = YES; + if (this->cp < this->cend-3 && strncmp((char *)this->cp, "!--", 3) == 0) {
#import <Foundation/Foundation.h> #define kTestCaseCount (6) typedef struct { const char *plist; size_t plistLength; const char *text; size_t textLength; } TestCase; static const TestCase sTestCases[kTestCaseCount]; static void RunTestCase(const TestCase *testCase, unsigned idx); int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; unsigned i; for (i = 0; i < kTestCaseCount; i++) { RunTestCase(&sTestCases[i], i + 1); } [pool release]; return 0; } static void RunTestCase(const TestCase *testCase, unsigned idx) { NSData *data = nil; NSString *errorDesc = nil; id plist = nil; NSString *plistValue = nil; NSString *expectedValue = nil; NS_DURING data = [NSData dataWithBytes:testCase->plist length:testCase->plistLength]; if (data == nil) { NSLog(@"Test case %u FAILED: could not construct plist data.", idx); NS_VOIDRETURN; } plist = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable format:NULL errorDescription:&errorDesc]; if (plist == nil) { NSLog(@"Test case %u FAILED: could not parse property list. Error string: %@", idx, errorDesc); NS_VOIDRETURN; } if (![plist isKindOfClass:[NSArray class]] || [plist count] != 1) { NSLog(@"Test case %u FAILED: plist content is not array with one member.", idx); NS_VOIDRETURN; } plistValue = [plist objectAtIndex:0]; if (![plistValue isKindOfClass:[NSString class]]) { NSLog(@"Test case %u FAILED: plist content is not an array with one string.", idx); NS_VOIDRETURN; } data = [NSData dataWithBytes:testCase->text length:testCase->textLength]; if (data == nil) { NSLog(@"Test case %u FAILED: could not construct string data.", idx); NS_VOIDRETURN; } expectedValue = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; [expectedValue autorelease]; if (expectedValue == nil) { NSLog(@"Test case %u FAILED: could not construct string from data (must be UTF-8).", idx); NS_VOIDRETURN; } if ([plistValue compare:expectedValue options:0] != NSOrderedSame) { NSLog(@"Test case %u FAILED: read string is wrong (expected \"%...@\", got \"%...@\").", idx, expectedValue, plistValue); NS_VOIDRETURN; } NS_HANDLER NSLog(@"Test case %u FAILED: exception thrown - %@ : %@", idx, [localException name], [localException reason]); return; NS_ENDHANDLER NSLog(@"Test case %u succeeded.", idx); } /* Test data follows. Data entries are UTF-8 strings, expressed as byte arrays to minimize risk of encoding problems. */ // Cyrillic string. static const char sTestPlist1[] = { 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x55, 0x54, 0x46, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x47, 0x4E, 0x55, 0x73, 0x74, 0x65, 0x70, 0x2F, 0x2F, 0x44, 0x54, 0x44, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x30, 0x2E, 0x39, 0x2F, 0x2F, 0x45, 0x4E, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x6E, 0x75, 0x73, 0x74, 0x65, 0x70, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x30, 0x5F, 0x39, 0x2E, 0x78, 0x6D, 0x6C, 0x22, 0x3E, 0x0A, 0x3C, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x30, 0x2E, 0x39, 0x22, 0x3E, 0x0A, 0x3C, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0xD0, 0x93, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xBE, 0xD1, 0x80, 0xD0, 0xB8, 0xD1, 0x82, 0x20, 0xD1, 0x81, 0xD1, 0x82, 0xD0, 0xB0, 0xD0, 0xBD, 0xD1, 0x86, 0xD0, 0xB8, 0xD1, 0x8F, 0x20, 0x4C, 0x61, 0x65, 0x6E, 0x69, 0x6E, 0x2E, 0x20, 0xD0, 0x9C, 0xD1, 0x8B, 0x20, 0xD0, 0xB7, 0xD0, 0xB0, 0xD0, 0xB3, 0xD1, 0x80, 0xD1, 0x83, 0xD0, 0xB7, 0xD0, 0xB8, 0xD0, 0xBB, 0xD0, 0xB8, 0x20, 0xD1, 0x81, 0xD1, 0x82, 0xD1, 0x8B, 0xD0, 0xBA, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xBE, 0xD1, 0x87, 0xD0, 0xBD, 0xD1, 0x8B, 0xD0, 0xB5, 0x20, 0xD0, 0xB8, 0xD0, 0xBD, 0xD1, 0x81, 0xD1, 0x82, 0xD1, 0x80, 0xD1, 0x83, 0xD0, 0xBA, 0xD1, 0x86, 0xD0, 0xB8, 0xD0, 0xB8, 0x20, 0xD0, 0xBD, 0xD0, 0xB0, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0x0A, 0x3C, 0x2F, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x3C, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x3E, 0x0A }; static const char sTestText1[] = { 0xD0, 0x93, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xBE, 0xD1, 0x80, 0xD0, 0xB8, 0xD1, 0x82, 0x20, 0xD1, 0x81, 0xD1, 0x82, 0xD0, 0xB0, 0xD0, 0xBD, 0xD1, 0x86, 0xD0, 0xB8, 0xD1, 0x8F, 0x20, 0x4C, 0x61, 0x65, 0x6E, 0x69, 0x6E, 0x2E, 0x20, 0xD0, 0x9C, 0xD1, 0x8B, 0x20, 0xD0, 0xB7, 0xD0, 0xB0, 0xD0, 0xB3, 0xD1, 0x80, 0xD1, 0x83, 0xD0, 0xB7, 0xD0, 0xB8, 0xD0, 0xBB, 0xD0, 0xB8, 0x20, 0xD1, 0x81, 0xD1, 0x82, 0xD1, 0x8B, 0xD0, 0xBA, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xBE, 0xD1, 0x87, 0xD0, 0xBD, 0xD1, 0x8B, 0xD0, 0xB5, 0x20, 0xD0, 0xB8, 0xD0, 0xBD, 0xD1, 0x81, 0xD1, 0x82, 0xD1, 0x80, 0xD1, 0x83, 0xD0, 0xBA, 0xD1, 0x86, 0xD0, 0xB8, 0xD0, 0xB8, 0x20, 0xD0, 0xBD, 0xD0, 0xB0, 0x20 }; // "A & B", using & static const char sTestPlist2[] = { 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x55, 0x54, 0x46, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x47, 0x4E, 0x55, 0x73, 0x74, 0x65, 0x70, 0x2F, 0x2F, 0x44, 0x54, 0x44, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x30, 0x2E, 0x39, 0x2F, 0x2F, 0x45, 0x4E, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x6E, 0x75, 0x73, 0x74, 0x65, 0x70, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x30, 0x5F, 0x39, 0x2E, 0x78, 0x6D, 0x6C, 0x22, 0x3E, 0x0A, 0x3C, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x30, 0x2E, 0x39, 0x22, 0x3E, 0x0A, 0x3C, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0x41, 0x20, 0x26, 0x61, 0x6D, 0x70, 0x3B, 0x20, 0x42, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0x0A, 0x3C, 0x2F, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x3C, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x3E, 0x0A }; static const char sTestText2[] = { 0x41, 0x20, 0x26, 0x20, 0x42 }; // Euro symbol (U+20AC), literal static const char sTestPlist3[] = { 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x55, 0x54, 0x46, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x47, 0x4E, 0x55, 0x73, 0x74, 0x65, 0x70, 0x2F, 0x2F, 0x44, 0x54, 0x44, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x30, 0x2E, 0x39, 0x2F, 0x2F, 0x45, 0x4E, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x6E, 0x75, 0x73, 0x74, 0x65, 0x70, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x30, 0x5F, 0x39, 0x2E, 0x78, 0x6D, 0x6C, 0x22, 0x3E, 0x0A, 0x3C, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x30, 0x2E, 0x39, 0x22, 0x3E, 0x0A, 0x3C, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0xE2, 0x82, 0xAC, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0x0A, 0x3C, 0x2F, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x3C, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x3E, 0x0A }; static const char sTestText3[] = { 0xE2, 0x82, 0xAC }; // Euro symbol (U+20AC), escaped as € static const char sTestPlist4[] = { 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x55, 0x54, 0x46, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x47, 0x4E, 0x55, 0x73, 0x74, 0x65, 0x70, 0x2F, 0x2F, 0x44, 0x54, 0x44, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x30, 0x2E, 0x39, 0x2F, 0x2F, 0x45, 0x4E, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x6E, 0x75, 0x73, 0x74, 0x65, 0x70, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x30, 0x5F, 0x39, 0x2E, 0x78, 0x6D, 0x6C, 0x22, 0x3E, 0x0A, 0x3C, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x30, 0x2E, 0x39, 0x22, 0x3E, 0x0A, 0x3C, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0xE2, 0x82, 0xAC, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0x0A, 0x3C, 0x2F, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x3C, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x3E, 0x0A }; static const char sTestText4[] = { 0xE2, 0x82, 0xAC }; // Cruzeiro symbol (U+20A2), literal static const char sTestPlist5[] = { 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x55, 0x54, 0x46, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x47, 0x4E, 0x55, 0x73, 0x74, 0x65, 0x70, 0x2F, 0x2F, 0x44, 0x54, 0x44, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x30, 0x2E, 0x39, 0x2F, 0x2F, 0x45, 0x4E, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x6E, 0x75, 0x73, 0x74, 0x65, 0x70, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x30, 0x5F, 0x39, 0x2E, 0x78, 0x6D, 0x6C, 0x22, 0x3E, 0x0A, 0x3C, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x30, 0x2E, 0x39, 0x22, 0x3E, 0x0A, 0x3C, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0xE2, 0x82, 0xA2, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0x0A, 0x3C, 0x2F, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x3C, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x3E, 0x0A }; static const char sTestText5[] = { 0xE2, 0x82, 0xA2 }; // "test " with trailing space static const char sTestPlist6[] = { 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x30, 0x22, 0x20, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x55, 0x54, 0x46, 0x2D, 0x38, 0x22, 0x3F, 0x3E, 0x0A, 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x47, 0x4E, 0x55, 0x73, 0x74, 0x65, 0x70, 0x2F, 0x2F, 0x44, 0x54, 0x44, 0x20, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x30, 0x2E, 0x39, 0x2F, 0x2F, 0x45, 0x4E, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x67, 0x6E, 0x75, 0x73, 0x74, 0x65, 0x70, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x2D, 0x30, 0x5F, 0x39, 0x2E, 0x78, 0x6D, 0x6C, 0x22, 0x3E, 0x0A, 0x3C, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x30, 0x2E, 0x39, 0x22, 0x3E, 0x0A, 0x3C, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x09, 0x3C, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0x74, 0x65, 0x73, 0x74, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3E, 0x0A, 0x3C, 0x2F, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3E, 0x0A, 0x3C, 0x2F, 0x70, 0x6C, 0x69, 0x73, 0x74, 0x3E, 0x0A }; static const char sTestText6[] = { 0x74, 0x65, 0x73, 0x74, 0x20 }; static const TestCase sTestCases[kTestCaseCount] = { { sTestPlist1, sizeof sTestPlist1, sTestText1, sizeof sTestText1 }, { sTestPlist2, sizeof sTestPlist2, sTestText2, sizeof sTestText2 }, { sTestPlist3, sizeof sTestPlist3, sTestText3, sizeof sTestText3 }, { sTestPlist4, sizeof sTestPlist4, sTestText4, sizeof sTestText4 }, { sTestPlist5, sizeof sTestPlist5, sTestText5, sizeof sTestText5 }, { sTestPlist6, sizeof sTestPlist6, sTestText6, sizeof sTestText6 } };
signature.asc
Description: This is a digitally signed message part