mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Fix #1679: "0x" was taken as a valid integer literal.
Fixes the tokenizer, tokenize.py and int() to reject this. Patches by Malte Helmert.
This commit is contained in:
		
							parent
							
								
									2686f4d9d1
								
							
						
					
					
						commit
						14404b68d8
					
				
					 6 changed files with 45 additions and 16 deletions
				
			
		|  | @ -816,6 +816,11 @@ def test_int(self): | ||||||
|         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 @@ def testPlainIntegers(self): | ||||||
|         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 @@ def maybe(*choices): return group(*choices) + '?' | ||||||
| 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? | ||||||
| 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) | ||||||
| 				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) | ||||||
| 
 | 
 | ||||||
| 	/* 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 */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Georg Brandl
						Georg Brandl