ObjFW  Diff

Differences From Artifact [4039ac2894]:

To Artifact [8741247447]:

  • File src/OFXMLParser.m — part of check-in [e1e7ffa903] at 2011-09-22 23:25:42 on branch trunk — Exceptions are now autoreleased.

    This is safe as an "exception loop" can't happen, since if allocating
    an exception fails, it throws an OFAllocFailedException which is
    preallocated and can always be thrown.

    So, the worst case would be that an autorelease of an exception fails,
    triggering an OFOutOfMemoryException for which there is no memory,
    resulting in an OFAllocFailedException to be thrown. (user: js, size: 25324) [annotate] [blame] [check-ins using]


116
117
118
119
120
121
122
123
124


125
126
127
128
129
130
131
116
117
118
119
120
121
122


123
124
125
126
127
128
129
130
131







-
-
+
+







	if (attributePrefix == nil)
		return;

	attributeNS = namespace_for_prefix(attributePrefix, namespaces);

	if ((attributePrefix != nil && attributeNS == nil))
		@throw [OFUnboundNamespaceException
		    newWithClass: isa
			  prefix: attributePrefix];
		    exceptionWithClass: isa
				prefix: attributePrefix];

	[attribute->ns release];
	attribute->ns = [attributeNS retain];
}

@implementation OFXMLParser
+ (void)initialize
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168







-
+







		@selector(_parseInDoctypeWithBuffer:i:last:),
	};
	memcpy(selectors, selectors_, sizeof(selectors_));

	for (i = 0; i < OF_XMLPARSER_NUM_STATES; i++) {
		if (![self instancesRespondToSelector: selectors[i]])
			@throw [OFInitializationFailedException
			    newWithClass: self];
			    exceptionWithClass: self];

		lookupTable[i] = (state_function)
		    [self instanceMethodForSelector: selectors[i]];
	}
}

+ parser
300
301
302
303
304
305
306
307
308


309
310
311
312
313
314
315
300
301
302
303
304
305
306


307
308
309
310
311
312
313
314
315







-
-
+
+







			      last: (size_t*)last
{
	size_t length;

	if ((finishedParsing || [previous count] < 1) && buffer[*i] != ' ' &&
	    buffer[*i] != '\t' && buffer[*i] != '\n' && buffer[*i] != '\r' &&
	    buffer[*i] != '\f' && buffer[*i] != '<')
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	if (buffer[*i] != '<')
		return;

	if ((length = *i - *last) > 0)
		cache_append(cache, buffer + *last, encoding, length);

334
335
336
337
338
339
340
341
342


343
344
345
346
347
348
349
334
335
336
337
338
339
340


341
342
343
344
345
346
347
348
349







-
-
+
+








/* Tag was just opened */
- (void)_parseTagOpenedWithBuffer: (const char*)buffer
				i: (size_t*)i
			     last: (size_t*)last
{
	if (finishedParsing && buffer[*i] != '!' && buffer[*i] != '?')
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	switch (buffer[*i]) {
		case '?':
			*last = *i + 1;
			state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS;
			level = 0;
			break;
477
478
479
480
481
482
483
484
485


486
487
488
489
490
491
492
477
478
479
480
481
482
483


484
485
486
487
488
489
490
491
492







-
-
+
+







		pi = transform_string(cache, 1, NO, nil);

		if ([pi isEqual: @"xml"] || [pi hasPrefix: @"xml "] ||
		    [pi hasPrefix: @"xml\t"] || [pi hasPrefix: @"xml\r"] ||
		    [pi hasPrefix: @"xml\n"])
			if (![self _parseXMLProcessingInstructions: pi])
				@throw [OFMalformedXMLException
				    newWithClass: isa
					parser: self];
				    exceptionWithClass: isa
						parser: self];

		[delegate parser: self
		    foundProcessingInstructions: pi];

		[pool release];

		[cache removeNItems: [cache count]];
537
538
539
540
541
542
543
544
545
546



547
548
549
550
551
552
553
537
538
539
540
541
542
543



544
545
546
547
548
549
550
551
552
553







-
-
-
+
+
+







	if (buffer[*i] == '>' || buffer[*i] == '/') {
		OFAutoreleasePool *pool2;
		OFString *ns;

		ns = namespace_for_prefix(prefix, namespaces);

		if (prefix != nil && ns == nil)
			@throw
			    [OFUnboundNamespaceException newWithClass: isa
							       prefix: prefix];
			@throw [OFUnboundNamespaceException
			    exceptionWithClass: isa
					prefix: prefix];

		pool2 = [[OFAutoreleasePool alloc] init];

		[delegate parser: self
		 didStartElement: name
		      withPrefix: prefix
		       namespace: ns
622
623
624
625
626
627
628
629
630


631
632
633
634
635
636
637
638
639


640
641
642
643
644
645
646
622
623
624
625
626
627
628


629
630
631
632
633
634
635
636
637


638
639
640
641
642
643
644
645
646







-
-
+
+







-
-
+
+







				length: tmp - cacheCString];
	} else {
		name = [cacheString copy];
		prefix = nil;
	}

	if (![[previous lastObject] isEqual: cacheString])
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	[previous removeLastObject];

	[cache removeNItems: [cache count]];

	ns = namespace_for_prefix(prefix, namespaces);
	if (prefix != nil && ns == nil)
		@throw [OFUnboundNamespaceException newWithClass: isa
							  prefix: prefix];
		@throw [OFUnboundNamespaceException exceptionWithClass: isa
								prefix: prefix];

	[delegate parser: self
	   didEndElement: name
	      withPrefix: prefix
	       namespace: ns];

	[pool release];
683
684
685
686
687
688
689
690
691


692
693
694
695
696
697
698
683
684
685
686
687
688
689


690
691
692
693
694
695
696
697
698







-
-
+
+








	attributesCArray = [attributes cArray];
	attributesCount = [attributes count];

	ns = namespace_for_prefix(prefix, namespaces);

	if (prefix != nil && ns == nil)
		@throw [OFUnboundNamespaceException newWithClass: isa
							  prefix: prefix];
		@throw [OFUnboundNamespaceException exceptionWithClass: isa
								prefix: prefix];

	for (j = 0; j < attributesCount; j++)
		resolve_attribute_namespace(attributesCArray[j], namespaces,
		    isa);

	pool = [[OFAutoreleasePool alloc] init];

788
789
790
791
792
793
794
795
796


797
798
799
800
801
802
803
788
789
790
791
792
793
794


795
796
797
798
799
800
801
802
803







-
-
+
+







	*last = *i + 1;

	if (buffer[*i] == ' ' || buffer[*i] == '\t' || buffer[*i] == '\n' ||
	    buffer[*i] == '\r' || buffer[*i] == '\f')
		return;

	if (buffer[*i] != '\'' && buffer[*i] != '"')
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	delimiter = buffer[*i];
	state = OF_XMLPARSER_IN_ATTR_VALUE;
}

/* Looking for attribute value */
- (void)_parseInAttributeValueWithBuffer: (const char*)buffer
848
849
850
851
852
853
854
855
856


857
858
859
860
861
862
863
864
865
866
867
868
869
870


871
872
873
874
875
876
877
878
879
880


881
882
883
884
885
886
887
888
889
890
891
892


893
894
895
896
897
898
899
900
901
902
903
904


905
906
907
908
909
910
911
848
849
850
851
852
853
854


855
856
857
858
859
860
861
862
863
864
865
866
867
868


869
870
871
872
873
874
875
876
877
878


879
880
881
882
883
884
885
886
887
888
889
890


891
892
893
894
895
896
897
898
899
900
901
902


903
904
905
906
907
908
909
910
911







-
-
+
+












-
-
+
+








-
-
+
+










-
-
+
+










-
-
+
+







				  i: (size_t*)i
			       last: (size_t*)last
{
	if (buffer[*i] == '>') {
		*last = *i + 1;
		state = OF_XMLPARSER_OUTSIDE_TAG;
	} else
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];
}

/* Expecting closing '>' or space */
- (void)_parseExpectSpaceOrCloseWithBuffer: (const char*)buffer
					 i: (size_t*)i
				      last: (size_t*)last
{
	if (buffer[*i] == '>') {
		*last = *i + 1;
		state = OF_XMLPARSER_OUTSIDE_TAG;
	} else if (buffer[*i] != ' ' && buffer[*i] != '\t' &&
	    buffer[*i] != '\n' && buffer[*i] != '\r' && buffer[*i] != '\f')
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];
}

/* In <! */
- (void)_parseInExclamationMarkWithBuffer: (const char*)buffer
					i: (size_t*)i
				     last: (size_t*)last
{
	if (finishedParsing && buffer[*i] != '-')
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	if (buffer[*i] == '-')
		state = OF_XMLPARSER_IN_COMMENT_OPENING;
	else if (buffer[*i] == '[') {
		state = OF_XMLPARSER_IN_CDATA_OPENING;
		level = 0;
	} else if (buffer[*i] == 'D') {
		state = OF_XMLPARSER_IN_DOCTYPE;
		level = 0;
	} else
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	*last = *i + 1;
}

/* CDATA */
- (void)_parseInCDATAOpeningWithBuffer: (const char*)buffer
				     i: (size_t*)i
				  last: (size_t*)last
{
	if (buffer[*i] != "CDATA["[level])
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	if (++level == 6) {
		state = OF_XMLPARSER_IN_CDATA_1;
		level = 0;
	}

	*last = *i + 1;
956
957
958
959
960
961
962
963
964


965
966
967
968
969
970
971
956
957
958
959
960
961
962


963
964
965
966
967
968
969
970
971







-
-
+
+








/* Comment */
- (void)_parseInCommentOpeningWithBuffer: (const char*)buffer
				       i: (size_t*)i
				    last: (size_t*)last
{
	if (buffer[*i] != '-')
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	*last = *i + 1;
	state = OF_XMLPARSER_IN_COMMENT_1;
	level = 0;
}

- (void)_parseInComment1WithBuffer: (const char*)buffer
985
986
987
988
989
990
991
992
993


994
995
996
997
998
999
1000
985
986
987
988
989
990
991


992
993
994
995
996
997
998
999
1000







-
-
+
+







				 i: (size_t*)i
			      last: (size_t*)last
{
	OFAutoreleasePool *pool;
	OFString *comment;

	if (buffer[*i] != '>')
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	pool = [[OFAutoreleasePool alloc] init];

	cache_append(cache, buffer + *last, encoding, *i - *last);
	comment = transform_string(cache, 2, NO, nil);

	[delegate parser: self
1012
1013
1014
1015
1016
1017
1018
1019
1020


1021
1022
1023
1024
1025
1026
1027
1012
1013
1014
1015
1016
1017
1018


1019
1020
1021
1022
1023
1024
1025
1026
1027







-
-
+
+







- (void)_parseInDoctypeWithBuffer: (const char*)buffer
				i: (size_t*)i
			     last: (size_t*)last
{
	if ((level < 6 && buffer[*i] != "OCTYPE"[level]) ||
	    (level == 6 && buffer[*i] != ' ' && buffer[*i] != '\t' &&
	    buffer[*i] != '\n' && buffer[*i] != '\r' && buffer[*i] != '\f'))
		@throw [OFMalformedXMLException newWithClass: isa
						      parser: self];
		@throw [OFMalformedXMLException exceptionWithClass: isa
							    parser: self];

	if (level < 7 || buffer[*i] == '<')
		level++;

	if (buffer[*i] == '>') {
		if (level == 7)
			state = OF_XMLPARSER_OUTSIDE_TAG;