Commits

Anonymous committed 8ef481c

Since this module is used as a fallback in case no built-in modules
have been configured, string.atof() should not fail when "import re"
fails (usually because pcre is not there).

This opens up a tiny security hole: *if* an attacker can make "import
re" fail, they can also make string.atof(arbitrary_string) evaluate
the arbitrary string. Nothing to keep me awake at night...

Comments (0)

Files changed (2)

 def atof(str):
 	global re
 	if re is None:
-		import re
+		# Don't fail if re doesn't exist -- just skip the syntax check
+		try:
+			import re
+		except ImportError:
+			re = 0
 	sign = ''
 	s = strip(str)
 	if s and s[0] in '+-':
 	if not s:
 		raise ValueError, 'non-float argument to string.atof'
 	while s[0] == '0' and len(s) > 1 and s[1] in digits: s = s[1:]
-	if not re.match('[0-9]*(\.[0-9]*)?([eE][-+]?[0-9]+)?$', s):
+	if re and not re.match('[0-9]*(\.[0-9]*)?([eE][-+]?[0-9]+)?$', s):
 		raise ValueError, 'non-float argument to string.atof'
 	try:
-		return float(eval(sign + s))
+		return float(eval(sign + s, {}))
 	except SyntaxError:
 		raise ValueError, 'non-float argument to string.atof'
 
 def atof(str):
 	global re
 	if re is None:
-		import re
+		# Don't fail if re doesn't exist -- just skip the syntax check
+		try:
+			import re
+		except ImportError:
+			re = 0
 	sign = ''
 	s = strip(str)
 	if s and s[0] in '+-':
 	if not s:
 		raise ValueError, 'non-float argument to string.atof'
 	while s[0] == '0' and len(s) > 1 and s[1] in digits: s = s[1:]
-	if not re.match('[0-9]*(\.[0-9]*)?([eE][-+]?[0-9]+)?$', s):
+	if re and not re.match('[0-9]*(\.[0-9]*)?([eE][-+]?[0-9]+)?$', s):
 		raise ValueError, 'non-float argument to string.atof'
 	try:
-		return float(eval(sign + s))
+		return float(eval(sign + s, {}))
 	except SyntaxError:
 		raise ValueError, 'non-float argument to string.atof'