|
41 | 41 | package com.oracle.graal.python.builtins.modules;
|
42 | 42 |
|
43 | 43 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.LookupError;
|
| 44 | +import static com.oracle.graal.python.runtime.exception.PythonErrorType.MemoryError; |
44 | 45 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
|
45 | 46 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.UnicodeDecodeError;
|
46 | 47 | import static com.oracle.graal.python.runtime.exception.PythonErrorType.UnicodeEncodeError;
|
@@ -143,22 +144,27 @@ void handle(TruffleEncoder encoder, String errorAction, Object inputObject,
|
143 | 144 | @Cached("createIdentityProfile()") ValueProfile actionProfile,
|
144 | 145 | @Cached RaiseEncodingErrorNode raiseEncodingErrorNode,
|
145 | 146 | @Cached PRaiseNode raiseNode) {
|
146 |
| - // Ignore and replace are handled by Java Charset |
147 |
| - switch (actionProfile.profile(errorAction)) { |
148 |
| - case STRICT: |
149 |
| - break; |
150 |
| - case BACKSLASHREPLACE: |
151 |
| - if (backslashreplace(encoder)) { |
152 |
| - return; |
153 |
| - } |
154 |
| - break; |
155 |
| - case SURROGATEPASS: |
156 |
| - if (surrogatepass(encoder)) { |
157 |
| - return; |
158 |
| - } |
159 |
| - break; |
160 |
| - default: |
161 |
| - raiseNode.raise(LookupError, ErrorMessages.UNKNOWN_ERROR_HANDLER, errorAction); |
| 147 | + try { |
| 148 | + // Ignore and replace are handled by Java Charset |
| 149 | + switch (actionProfile.profile(errorAction)) { |
| 150 | + case STRICT: |
| 151 | + break; |
| 152 | + case BACKSLASHREPLACE: |
| 153 | + if (backslashreplace(encoder)) { |
| 154 | + return; |
| 155 | + } |
| 156 | + break; |
| 157 | + case SURROGATEPASS: |
| 158 | + if (surrogatepass(encoder)) { |
| 159 | + return; |
| 160 | + } |
| 161 | + break; |
| 162 | + default: |
| 163 | + raiseNode.raise(LookupError, ErrorMessages.UNKNOWN_ERROR_HANDLER, errorAction); |
| 164 | + } |
| 165 | + } catch (OutOfMemoryError e) { |
| 166 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 167 | + throw raiseNode.raise(MemoryError); |
162 | 168 | }
|
163 | 169 | throw raiseEncodingErrorNode.execute(encoder, inputObject);
|
164 | 170 | }
|
@@ -401,9 +407,15 @@ private PBytes encodeString(Object self, String input, String encoding, String e
|
401 | 407 | if (charset == null) {
|
402 | 408 | throw raise(LookupError, ErrorMessages.UNKNOWN_ENCODING, encoding);
|
403 | 409 | }
|
404 |
| - TruffleEncoder encoder = new TruffleEncoder(CharsetMapping.normalize(encoding), charset, input, errorAction); |
405 |
| - while (!encoder.encodingStep()) { |
406 |
| - handleEncodingError(encoder, errors, self); |
| 410 | + TruffleEncoder encoder; |
| 411 | + try { |
| 412 | + encoder = new TruffleEncoder(CharsetMapping.normalize(encoding), charset, input, errorAction); |
| 413 | + while (!encoder.encodingStep()) { |
| 414 | + handleEncodingError(encoder, errors, self); |
| 415 | + } |
| 416 | + } catch (OutOfMemoryError e) { |
| 417 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 418 | + throw raise(MemoryError); |
407 | 419 | }
|
408 | 420 | return factory().createBytes(encoder.getBytes());
|
409 | 421 | }
|
@@ -466,9 +478,15 @@ Object decodeBytes(PBytesLike input, String encoding, String errors, boolean fin
|
466 | 478 | if (charset == null) {
|
467 | 479 | throw raise(LookupError, ErrorMessages.UNKNOWN_ENCODING, encoding);
|
468 | 480 | }
|
469 |
| - TruffleDecoder decoder = new TruffleDecoder(CharsetMapping.normalize(encoding), charset, bytes, errorAction); |
470 |
| - while (!decoder.decodingStep(finalData)) { |
471 |
| - handleDecodingError(decoder, errors, input); |
| 481 | + TruffleDecoder decoder; |
| 482 | + try { |
| 483 | + decoder = new TruffleDecoder(CharsetMapping.normalize(encoding), charset, bytes, errorAction); |
| 484 | + while (!decoder.decodingStep(finalData)) { |
| 485 | + handleDecodingError(decoder, errors, input); |
| 486 | + } |
| 487 | + } catch (OutOfMemoryError e) { |
| 488 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 489 | + throw raise(MemoryError); |
472 | 490 | }
|
473 | 491 | return factory().createTuple(new Object[]{decoder.getString(), decoder.getInputPosition()});
|
474 | 492 | }
|
@@ -597,7 +615,13 @@ public boolean encodingStep() {
|
597 | 615 | }
|
598 | 616 |
|
599 | 617 | private void grow() {
|
600 |
| - ByteBuffer newBuffer = ByteBuffer.allocate(2 * outputBuffer.capacity() + 1); |
| 618 | + int newCapacity = 2 * outputBuffer.capacity() + 1; |
| 619 | + // Overflow check - (2 * Integer.MAX_VALUE + 1 == -1) => overflown result cannot be |
| 620 | + // positive |
| 621 | + if (newCapacity < 0) { |
| 622 | + throw new OutOfMemoryError(); |
| 623 | + } |
| 624 | + ByteBuffer newBuffer = ByteBuffer.allocate(newCapacity); |
601 | 625 | outputBuffer.flip();
|
602 | 626 | newBuffer.put(outputBuffer);
|
603 | 627 | outputBuffer = newBuffer;
|
@@ -706,7 +730,13 @@ public boolean decodingStep(boolean finalData) {
|
706 | 730 | }
|
707 | 731 |
|
708 | 732 | private void grow() {
|
709 |
| - CharBuffer newBuffer = CharBuffer.allocate(2 * outputBuffer.capacity() + 1); |
| 733 | + int newCapacity = 2 * outputBuffer.capacity() + 1; |
| 734 | + // Overflow check - (2 * Integer.MAX_VALUE + 1 == -1) => overflown result cannot be |
| 735 | + // positive |
| 736 | + if (newCapacity < 0) { |
| 737 | + throw new OutOfMemoryError(); |
| 738 | + } |
| 739 | + CharBuffer newBuffer = CharBuffer.allocate(newCapacity); |
710 | 740 | outputBuffer.flip();
|
711 | 741 | newBuffer.put(outputBuffer);
|
712 | 742 | outputBuffer = newBuffer;
|
|
0 commit comments