diff --git a/HTMLKit/HTMLInputStreamReader.h b/HTMLKit/HTMLInputStreamReader.h
index 372ce50..12a7f2e 100644
--- a/HTMLKit/HTMLInputStreamReader.h
+++ b/HTMLKit/HTMLInputStreamReader.h
@@ -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;
diff --git a/HTMLKit/HTMLInputStreamReader.m b/HTMLKit/HTMLInputStreamReader.m
index 9ff56e3..b801ffe 100644
--- a/HTMLKit/HTMLInputStreamReader.m
+++ b/HTMLKit/HTMLInputStreamReader.m
@@ -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;
}
diff --git a/HTMLKit/HTMLTokenizer.m b/HTMLKit/HTMLTokenizer.m
index 51537a8..ff99493 100644
--- a/HTMLKit/HTMLTokenizer.m
+++ b/HTMLKit/HTMLTokenizer.m
@@ -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
diff --git a/HTMLKit/HTMLTokenizerCharacters.h b/HTMLKit/HTMLTokenizerCharacters.h
index 403509d..5071ead 100644
--- a/HTMLKit/HTMLTokenizerCharacters.h
+++ b/HTMLKit/HTMLTokenizerCharacters.h
@@ -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)