ObjFW  Check-in [7aa0a50f2f]

Overview
Comment:Better handling of \n and \r in OFXMLParser.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 7aa0a50f2f1533187f49f1a617ccb31ab29e6c3d4602ce650828ab27e6dbc249
User & Date: js on 2010-05-13 18:27:49
Other Links: manifest | tags
Context
2010-05-16
19:24
objc_sync was still using the old threads API. Fixed. check-in: 42dedf0153 user: js tags: trunk
2010-05-13
18:27
Better handling of \n and \r in OFXMLParser. check-in: 7aa0a50f2f user: js tags: trunk
17:11
Add -[remainderOfDivisionWithNumber:] to OFNumber. check-in: 8fd09d2c59 user: js tags: trunk
Changes

Modified src/OFXMLParser.m from [e53641c3ce] to [cd6f6b17e5].

178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
				state = OF_XMLPARSER_IN_TAG_NAME;
				i--;
			}
			break;

		/* Inside a tag, no name yet */
		case OF_XMLPARSER_IN_TAG_NAME:
			if (buf[i] == ' ' || buf[i] == '>' || buf[i] == '/') {

				const char *cache_c, *tmp;
				size_t cache_len;

				len = i - last;
				if (len > 0)
					[cache appendCString: buf + last
						  withLength: len];







|
>







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
				state = OF_XMLPARSER_IN_TAG_NAME;
				i--;
			}
			break;

		/* Inside a tag, no name yet */
		case OF_XMLPARSER_IN_TAG_NAME:
			if (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r' ||
			    buf[i] == '>' || buf[i] == '/') {
				const char *cache_c, *tmp;
				size_t cache_len;

				len = i - last;
				if (len > 0)
					[cache appendCString: buf + last
						  withLength: len];
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
				[cache setToCString: ""];
				last = i + 1;
			}
			break;

		/* Inside a close tag, no name yet */
		case OF_XMLPARSER_IN_CLOSE_TAG_NAME:
			if (buf[i] == ' ' || buf[i] == '>') {

				const char *cache_c, *tmp;
				size_t cache_len;

				len = i - last;
				if (len > 0)
					[cache appendCString: buf + last
						  withLength: len];







|
>







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
				[cache setToCString: ""];
				last = i + 1;
			}
			break;

		/* Inside a close tag, no name yet */
		case OF_XMLPARSER_IN_CLOSE_TAG_NAME:
			if (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r' ||
			    buf[i] == '>') {
				const char *cache_c, *tmp;
				size_t cache_len;

				len = i - last;
				if (len > 0)
					[cache appendCString: buf + last
						  withLength: len];
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302

				[name release];
				[prefix release];
				[ns release];
				name = prefix = ns = nil;

				last = i + 1;
				state = (buf[i] == ' '

				    ? OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE
				    : OF_XMLPARSER_OUTSIDE_TAG);
			}
			break;

		/* Inside a tag, name found */
		case OF_XMLPARSER_IN_TAG:







|
>







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

				[name release];
				[prefix release];
				[ns release];
				name = prefix = ns = nil;

				last = i + 1;
				state = (buf[i] == ' ' || buf[i] == '\n' ||
				    buf[i] == '\r'
				    ? OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE
				    : OF_XMLPARSER_OUTSIDE_TAG);
			}
			break;

		/* Inside a tag, name found */
		case OF_XMLPARSER_IN_TAG:
332
333
334
335
336
337
338
339

340
341
342
343
344
345
346
				name = prefix = ns = nil;
				attrs = nil;

				last = i + 1;
				state = (buf[i] == '/'
				    ? OF_XMLPARSER_EXPECT_CLOSE
				    : OF_XMLPARSER_OUTSIDE_TAG);
			} else if (buf[i] != ' ') {

				last = i;
				state = OF_XMLPARSER_IN_ATTR_NAME;
				i--;
			}
			break;

		/* Looking for attribute name */







|
>







335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
				name = prefix = ns = nil;
				attrs = nil;

				last = i + 1;
				state = (buf[i] == '/'
				    ? OF_XMLPARSER_EXPECT_CLOSE
				    : OF_XMLPARSER_OUTSIDE_TAG);
			} else if (buf[i] != ' ' && buf[i] != '\n' &&
			    buf[i] != '\r') {
				last = i;
				state = OF_XMLPARSER_IN_ATTR_NAME;
				i--;
			}
			break;

		/* Looking for attribute name */
433
434
435
436
437
438
439
440

441
442
443
444
445
446
447
			break;

		/* Expecting closing '>' or space */
		case OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE:
			if (buf[i] == '>') {
				last = i + 1;
				state = OF_XMLPARSER_OUTSIDE_TAG;
			} else if (buf[i] != ' ')

				@throw [OFMalformedXMLException
				    newWithClass: isa];
			break;

		/* Comment */
		case OF_XMLPARSER_IN_COMMENT_1:
		case OF_XMLPARSER_IN_COMMENT_2:







|
>







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
			break;

		/* Expecting closing '>' or space */
		case OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE:
			if (buf[i] == '>') {
				last = i + 1;
				state = OF_XMLPARSER_OUTSIDE_TAG;
			} else if (buf[i] != ' ' && buf[i] != '\n' &&
			    buf[i] != '\r')
				@throw [OFMalformedXMLException
				    newWithClass: isa];
			break;

		/* Comment */
		case OF_XMLPARSER_IN_COMMENT_1:
		case OF_XMLPARSER_IN_COMMENT_2:

Modified tests/OFXMLParserTests.m from [d66604b68c] to [7f2966e759].

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
		break;
	case 10:
		/* FIXME: Namespace */
		TEST(msg, et == TAG_END && [name isEqual: @"bar"] &&
		    [prefix isEqual: @"foo"] && ns == nil)
		break;
	case 11:
		TEST(msg, et == COMMENT && [comment isEqual: @"foo bär-baz"])
		break;
	default:
		TEST(msg, NO)
		break;
	}
}








|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
		break;
	case 10:
		/* FIXME: Namespace */
		TEST(msg, et == TAG_END && [name isEqual: @"bar"] &&
		    [prefix isEqual: @"foo"] && ns == nil)
		break;
	case 11:
		TEST(msg, et == COMMENT && [comment isEqual: @"foobär baz"])
		break;
	default:
		TEST(msg, NO)
		break;
	}
}

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
	return nil;
}

- (void)XMLParserTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLParser *parser;
	const char *str = "bar<foo:bar  bar='b&amp;az'  qux:qux=\" quux \">\r\n"
	    "foo&lt;bar<qux  >bar <baz name='' test='&foo;'/>  quxbar\r\n</qux>"
	    "</foo:bar><!-- foo bär-baz -->";
	size_t j, len;

	TEST(@"+[xmlParser]", (parser = [OFXMLParser xmlParser]))

	TEST(@"-[setDelegate:]", R([parser setDelegate: self]))

	/* Simulate a stream where we only get chunks */







|
|
|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
	return nil;
}

- (void)XMLParserTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLParser *parser;
	const char *str = "bar<foo:bar\r\n  bar='b&amp;az'\r  "
	    "qux:qux=\" quux \">\r\nfoo&lt;bar<qux \n>bar <baz name='' "
	    "test='&foo;'/>  quxbar\r\n</qux></foo:bar><!-- foobär baz -->";
	size_t j, len;

	TEST(@"+[xmlParser]", (parser = [OFXMLParser xmlParser]))

	TEST(@"-[setDelegate:]", R([parser setDelegate: self]))

	/* Simulate a stream where we only get chunks */