Commit dcebac63 authored by Georg Brandl's avatar Georg Brandl

Fix #1679: "0x" was taken as a valid integer literal.

Fixes the tokenizer, tokenize.py and int() to reject this.
Patches by Malte Helmert.
parent 9db0b80b
...@@ -816,6 +816,11 @@ class BuiltinTest(unittest.TestCase): ...@@ -816,6 +816,11 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(int('0123', 0), 83) self.assertEqual(int('0123', 0), 83)
self.assertEqual(int('0x123', 16), 291) self.assertEqual(int('0x123', 16), 291)
# Bug 1679: "0x" is not a valid hex literal
self.assertRaises(ValueError, int, "0x", 16)
self.assertRaises(ValueError, int, "0x", 0)
# SF bug 1334662: int(string, base) wrong answers # SF bug 1334662: int(string, base) wrong answers
# Various representations of 2**32 evaluated to 0 # Various representations of 2**32 evaluated to 0
# rather than 2**32 in previous versions # rather than 2**32 in previous versions
......
...@@ -30,6 +30,8 @@ class TokenTests(unittest.TestCase): ...@@ -30,6 +30,8 @@ class TokenTests(unittest.TestCase):
self.assertEquals(0xff, 255) self.assertEquals(0xff, 255)
self.assertEquals(0377, 255) self.assertEquals(0377, 255)
self.assertEquals(2147483647, 017777777777) self.assertEquals(2147483647, 017777777777)
# "0x" is not a valid literal
self.assertRaises(SyntaxError, eval, "0x")
from sys import maxint from sys import maxint
if maxint == 2147483647: if maxint == 2147483647:
self.assertEquals(-2147483647-1, -020000000000) self.assertEquals(-2147483647-1, -020000000000)
......
...@@ -50,7 +50,7 @@ Comment = r'#[^\r\n]*' ...@@ -50,7 +50,7 @@ Comment = r'#[^\r\n]*'
Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
Name = r'[a-zA-Z_]\w*' Name = r'[a-zA-Z_]\w*'
Hexnumber = r'0[xX][\da-fA-F]*[lL]?' Hexnumber = r'0[xX][\da-fA-F]+[lL]?'
Octnumber = r'0[0-7]*[lL]?' Octnumber = r'0[0-7]*[lL]?'
Decnumber = r'[1-9]\d*[lL]?' Decnumber = r'[1-9]\d*[lL]?'
Intnumber = group(Hexnumber, Octnumber, Decnumber) Intnumber = group(Hexnumber, Octnumber, Decnumber)
......
...@@ -12,6 +12,8 @@ What's New in Python 2.6 alpha 1? ...@@ -12,6 +12,8 @@ What's New in Python 2.6 alpha 1?
Core and builtins Core and builtins
----------------- -----------------
- Issue #1679: "0x" was taken as a valid integer literal.
- Issue #1865: Bytes as an alias for str and b"" as an alias "" were - Issue #1865: Bytes as an alias for str and b"" as an alias "" were
added. added.
......
...@@ -1332,7 +1332,14 @@ tok_get(register struct tok_state *tok, char **p_start, char **p_end) ...@@ -1332,7 +1332,14 @@ tok_get(register struct tok_state *tok, char **p_start, char **p_end)
goto imaginary; goto imaginary;
#endif #endif
if (c == 'x' || c == 'X') { if (c == 'x' || c == 'X') {
/* Hex */ /* Hex */
c = tok_nextc(tok);
if (!isxdigit(c)) {
tok->done = E_TOKEN;
tok_backup(tok, c);
return ERRORTOKEN;
}
do { do {
c = tok_nextc(tok); c = tok_nextc(tok);
} while (isxdigit(c)); } while (isxdigit(c));
......
...@@ -112,27 +112,40 @@ PyOS_strtoul(register char *str, char **ptr, int base) ...@@ -112,27 +112,40 @@ PyOS_strtoul(register char *str, char **ptr, int base)
/* check for leading 0 or 0x for auto-base or base 16 */ /* check for leading 0 or 0x for auto-base or base 16 */
switch (base) { switch (base) {
case 0: /* look for leading 0, 0x or 0X */ case 0: /* look for leading 0, 0x or 0X */
if (*str == '0') { if (*str == '0') {
++str; ++str;
if (*str == 'x' || *str == 'X') { if (*str == 'x' || *str == 'X') {
++str; /* there must be at least one digit after 0x */
base = 16; if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
if (ptr)
*ptr = str;
return 0;
} }
else ++str;
base = 8; base = 16;
} }
else else
base = 10; base = 8;
break; }
else
base = 10;
break;
case 16: /* skip leading 0x or 0X */ case 16: /* skip leading 0x or 0X */
if (*str == '0') { if (*str == '0') {
++str;
if (*str == 'x' || *str == 'X') {
/* there must be at least one digit after 0x */
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
if (ptr)
*ptr = str;
return 0;
}
++str; ++str;
if (*str == 'x' || *str == 'X')
++str;
} }
break; }
break;
} }
/* catch silly bases */ /* catch silly bases */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment