Fix parsing numeric entities
Numbers > UINT_MAX should be handled correctly now
This commit is contained in:
@@ -28,8 +28,8 @@
|
||||
- (void)unconsumeCurrentInputCharacter;
|
||||
|
||||
- (BOOL)consumeCharacter:(UTF32Char)character;
|
||||
- (BOOL)consumeUnsignedInt:(unsigned int *)result;
|
||||
- (BOOL)consumeHexInt:(unsigned int *)result;
|
||||
- (BOOL)consumeNumber:(unsigned long long *)result;
|
||||
- (BOOL)consumeHexNumber:(unsigned long long *)result;
|
||||
- (BOOL)consumeString:(NSString *)string caseSensitive:(BOOL)caseSensitive;
|
||||
- (NSString *)consumeCharactersUpToCharactersInString:(NSString *)characters;
|
||||
- (NSString *)consumeCharactersUpToString:(NSString *)string;
|
||||
|
||||
@@ -111,28 +111,27 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)consumeUnsignedInt:(unsigned int *)result
|
||||
- (BOOL)consumeNumber:(unsigned long long *)result
|
||||
{
|
||||
long long scanned;
|
||||
BOOL success = [_scanner scanLongLong:&scanned];
|
||||
if (success == NO || scanned < 0) return NO;
|
||||
if (result != NULL) {
|
||||
*result = MIN(UINT_MAX, (unsigned int)scanned);
|
||||
}
|
||||
unsigned long long scanned;
|
||||
BOOL success = [_scanner scanUnsignedLongLong:&scanned];
|
||||
if (success == NO) return NO;
|
||||
|
||||
*result = scanned;
|
||||
_location = _scanner.scanLocation;
|
||||
return success;
|
||||
}
|
||||
|
||||
- (BOOL)consumeHexInt:(unsigned int *)result
|
||||
- (BOOL)consumeHexNumber:(unsigned long long *)result
|
||||
{
|
||||
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEFabcdef"];
|
||||
|
||||
NSString *string = nil;
|
||||
BOOL success = [_scanner scanCharactersFromSet:set intoString:&string];
|
||||
if (success == NO) return NO;
|
||||
if (result != NULL) {
|
||||
*result = MIN(UINT_MAX, (unsigned int)strtoull(string.UTF8String, NULL, 16));
|
||||
}
|
||||
|
||||
unsigned long long scanned = strtoull(string.UTF8String, NULL, 16);
|
||||
*result = scanned;
|
||||
_location = _scanner.scanLocation;
|
||||
return success;
|
||||
}
|
||||
|
||||
+13
-10
@@ -268,17 +268,17 @@
|
||||
[_inputStreamReader consumeNextInputCharacter];
|
||||
|
||||
UTF32Char character = [_inputStreamReader nextInputCharacter];
|
||||
unsigned int number;
|
||||
unsigned long long number;
|
||||
BOOL success;
|
||||
|
||||
switch (character) {
|
||||
case LATIN_CAPITAL_LETTER_X:
|
||||
case LATIN_SMALL_LETTER_X:
|
||||
[_inputStreamReader consumeNextInputCharacter];
|
||||
success = [_inputStreamReader consumeHexInt:&number];
|
||||
success = [_inputStreamReader consumeHexNumber:&number];
|
||||
break;
|
||||
default:
|
||||
success = [_inputStreamReader consumeUnsignedInt:&number];
|
||||
success = [_inputStreamReader consumeNumber:&number];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -292,20 +292,23 @@
|
||||
[self emitParseError:@"Missing semicolon in numeric entity"];
|
||||
}
|
||||
|
||||
unichar numericReplacement = NumericReplacementCharacter(number);
|
||||
if (numericReplacement != NULL_CHAR) {
|
||||
[self emitParseError:@"Invalid numeric entity (a defenied replacement exists)"];
|
||||
return StringFromUniChar(numericReplacement);
|
||||
}
|
||||
if (isInvalidNumericRange(number)) {
|
||||
[self emitParseError:@"Invalid numeric entity (invalid Unicode range)"];
|
||||
return StringFromUniChar(REPLACEMENT_CHAR);
|
||||
}
|
||||
if (isControlOrUndefinedCharacter(number)) {
|
||||
|
||||
UTF32Char numericChar = (UTF32Char)number;
|
||||
unichar numericReplacement = NumericReplacementCharacter(numericChar);
|
||||
if (numericReplacement != NULL_CHAR) {
|
||||
[self emitParseError:@"Invalid numeric entity (a defenied replacement exists)"];
|
||||
return StringFromUniChar(numericReplacement);
|
||||
}
|
||||
|
||||
if (isControlOrUndefinedCharacter(numericChar)) {
|
||||
[self emitParseError:@"Invalid numeric entity (control or undefined character)"];
|
||||
}
|
||||
|
||||
return StringFromUTF32Char(number);
|
||||
return StringFromUTF32Char(numericChar);
|
||||
}
|
||||
|
||||
- (NSString *)attemptToConsumeNamedCharacterReferenceInAttribute:(BOOL)inAttribute
|
||||
|
||||
@@ -151,10 +151,10 @@ NS_INLINE BOOL isStringAlphanumeric(NSString *string)
|
||||
return ([string rangeOfCharacterFromSet:set].location == NSNotFound);
|
||||
}
|
||||
|
||||
NS_INLINE BOOL isInvalidNumericRange(UTF32Char character)
|
||||
NS_INLINE BOOL isInvalidNumericRange(unsigned long long numeric)
|
||||
{
|
||||
return ((character >= 0xD800 && character <= 0xDFFF) ||
|
||||
character > 0x10FFFF);
|
||||
return ((numeric >= 0xD800 && numeric <= 0xDFFF) ||
|
||||
numeric > 0x10FFFF);
|
||||
}
|
||||
|
||||
NS_INLINE unichar NumericReplacementCharacter(UTF32Char character)
|
||||
|
||||
Reference in New Issue
Block a user