Skip to content

Commit c94fc35

Browse files
committed
Fix NPE in string formatting
1 parent d469abc commit c94fc35

File tree

2 files changed

+17
-22
lines changed

2 files changed

+17
-22
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_string.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def test_format():
104104
assert "{0}.{1}".format("part1", "part2") == "part1.part2"
105105
assert "{1}.{0}".format("part1", "part2") == "part2.part1"
106106
assert "{}".format("part1") == "part1"
107+
assert "{0[-1]}".format({'-1': 'asdf'}) == 'asdf'
107108

108109

109110
class FormattingTestClass:

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/TemplateFormatter.java

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
import com.oracle.graal.python.lib.PyObjectReprAsObjectNode;
7676
import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode;
7777
import com.oracle.graal.python.nodes.PRaiseNode;
78-
import com.oracle.graal.python.runtime.exception.PException;
7978
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
8079
import com.oracle.truffle.api.nodes.Node;
8180
import com.oracle.truffle.api.strings.TruffleString;
@@ -262,11 +261,7 @@ private Object getArgument(Node node, String name, PyObjectGetItem getItemNode)
262261
if (isEmpty) {
263262
index = -1;
264263
} else {
265-
try {
266-
index = toInt(node, intString);
267-
} catch (NumberFormatException | ArrayIndexOutOfBoundsException nfe1) {
268-
index = -1;
269-
}
264+
index = toInt(node, intString);
270265
}
271266
boolean useNumeric = isEmpty || index != -1;
272267
if (this.autoNumberingState == ANS_INIT && useNumeric) {
@@ -348,19 +343,12 @@ private Object resolveLookups(Node node, Object obj, String name, int startArg,
348343
if (!gotBracket) {
349344
throw PRaiseNode.raiseUncached(node, ValueError, MISSING_S, "']'");
350345
}
351-
Object item = null;
352-
int index = -1;
353-
try {
354-
index = toInt(node, name.substring(start, i));
355-
} catch (NumberFormatException | ArrayIndexOutOfBoundsException nfe1) {
356-
item = toTruffleStringUncached(name.substring(start, i));
357-
}
358-
if (index > -1) {
359-
if (index > SysModuleBuiltins.MAXSIZE) {
360-
throw PRaiseNode.raiseUncached(node, ValueError, TOO_MANY_DECIMAL_DIGITS_IN_FORMAT_STRING);
361-
}
362-
item = index;
346+
String s = name.substring(start, i);
347+
if (s.isEmpty()) {
348+
throw PRaiseNode.raiseUncached(node, ValueError, EMPTY_ATTR_IN_FORMAT_STR);
363349
}
350+
int index = toInt(node, s);
351+
Object item = index != -1 ? index : toTruffleStringUncached(s);
364352
i += 1; // # Skip "]"
365353
if (result != null) {
366354
result = getItemNode.execute(null, result, item);
@@ -374,12 +362,18 @@ private Object resolveLookups(Node node, Object obj, String name, int startArg,
374362
return result;
375363
}
376364

377-
private static int toInt(Node node, String s) throws PException {
378-
BigInteger bigInt = new BigInteger(s);
379-
if (bigInt.compareTo(MAXSIZE) > 0) {
365+
private static int toInt(Node node, String s) {
366+
try {
367+
BigInteger bigInt = new BigInteger(s);
368+
if (bigInt.signum() >= 0) {
369+
return bigInt.intValueExact();
370+
}
371+
return -1;
372+
} catch (NumberFormatException e) {
373+
return -1;
374+
} catch (ArithmeticException e) {
380375
throw PRaiseNode.raiseUncached(node, ValueError, TOO_MANY_DECIMAL_DIGITS_IN_FORMAT_STRING);
381376
}
382-
return bigInt.intValue();
383377
}
384378

385379
private Object renderField(Node node, int start, int end, boolean recursive, int level, FormatNode formatNode, PyObjectGetItem getItemNode) {

0 commit comments

Comments
 (0)