Skip to content

Commit 8042c33

Browse files
committed
[GR-28951] Avoid xerces-internal codec
PullRequest: graalpython/1568
2 parents 070fe7b + d2239e0 commit 8042c33

File tree

2 files changed

+40
-81
lines changed

2 files changed

+40
-81
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ public enum PythonBuiltinClassType implements TruffleObject {
209209
SocketGAIError("gaierror", "_socket"),
210210
SocketHError("herror", "_socket"),
211211
SocketTimeout("timeout", "_socket"),
212+
BinasciiError("Error", "binascii"),
213+
BinasciiIncomplete("Incomplete", "binascii"),
212214

213215
// todo: all OS errors
214216

@@ -396,6 +398,8 @@ public final Shape getInstanceShape(PythonLanguage lang) {
396398
UnicodeTranslateError.base = UnicodeError;
397399
RecursionError.base = RuntimeError;
398400
StructError.base = Exception;
401+
BinasciiError.base = ValueError;
402+
BinasciiIncomplete.base = Exception;
399403

400404
// warnings
401405
Warning.base = Exception;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java

Lines changed: 36 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,13 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules;
4242

43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.BinasciiError;
4344
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
44-
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
4545
import static com.oracle.graal.python.runtime.exception.PythonErrorType.SystemError;
4646

47+
import java.nio.charset.StandardCharsets;
48+
import java.util.Arrays;
49+
import java.util.Base64;
4750
import java.util.List;
4851
import java.util.zip.CRC32;
4952

@@ -53,24 +56,15 @@
5356
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5457
import com.oracle.graal.python.builtins.PythonBuiltins;
5558
import com.oracle.graal.python.builtins.objects.PNone;
56-
import com.oracle.graal.python.builtins.objects.bytes.BytesUtils;
5759
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
5860
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
59-
import com.oracle.graal.python.builtins.objects.module.PythonModule;
6061
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
61-
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
6262
import com.oracle.graal.python.nodes.ErrorMessages;
63-
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
64-
import com.oracle.graal.python.nodes.call.CallNode;
6563
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
6664
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
6765
import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
6866
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
6967
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
70-
import com.oracle.graal.python.nodes.statement.RaiseNode;
71-
import com.oracle.graal.python.nodes.statement.RaiseNodeGen;
72-
import com.oracle.graal.python.runtime.PythonCore;
73-
import com.oracle.graal.python.runtime.exception.PException;
7468
import com.oracle.truffle.api.CompilerDirectives;
7569
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
7670
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -81,28 +75,15 @@
8175
import com.oracle.truffle.api.dsl.Specialization;
8276
import com.oracle.truffle.api.interop.UnsupportedMessageException;
8377
import com.oracle.truffle.api.library.CachedLibrary;
84-
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
8578

8679
@CoreFunctions(defineModule = "binascii")
8780
public class BinasciiModuleBuiltins extends PythonBuiltins {
88-
private static final String INCOMPLETE = "Incomplete";
89-
private static final String ERROR = "Error";
9081

9182
@Override
9283
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
9384
return BinasciiModuleBuiltinsFactory.getFactories();
9485
}
9586

96-
@Override
97-
public void initialize(PythonCore core) {
98-
super.initialize(core);
99-
String pre = "binascii.";
100-
PythonAbstractClass[] errorBases = new PythonAbstractClass[]{core.lookupType(PythonBuiltinClassType.ValueError)};
101-
builtinConstants.put(ERROR, core.factory().createPythonClass(PythonBuiltinClassType.PythonClass, pre + ERROR, errorBases));
102-
PythonAbstractClass[] incompleteBases = new PythonAbstractClass[]{core.lookupType(PythonBuiltinClassType.Exception)};
103-
builtinConstants.put(INCOMPLETE, core.factory().createPythonClass(PythonBuiltinClassType.PythonClass, pre + INCOMPLETE, incompleteBases));
104-
}
105-
10687
@Builtin(name = "a2b_base64", minNumOfPositionalArgs = 1)
10788
@GenerateNodeFactory
10889
abstract static class A2bBase64Node extends PythonUnaryBuiltinNode {
@@ -122,124 +103,98 @@ PBytes doBuffer(Object data,
122103
}
123104

124105
@TruffleBoundary
125-
private static byte[] b64decode(String data) {
126-
return Base64.decode(data);
106+
private byte[] b64decode(String data) {
107+
return b64decode(data.getBytes(StandardCharsets.US_ASCII));
127108
}
128109

129110
@TruffleBoundary
130111
private byte[] b64decode(byte[] data) {
131-
byte[] asciis = Base64.decode(BytesUtils.createASCIIString(data));
132-
if (asciis != null) {
133-
return asciis;
112+
try {
113+
// Using MIME decoder because that one skips over anything that is not the alphabet,
114+
// just like CPython does
115+
return Base64.getMimeDecoder().decode(data);
116+
} catch (IllegalArgumentException e) {
117+
throw raise(BinasciiError, e);
134118
}
135-
throw raise(ValueError);
136119
}
137120
}
138121

139-
@Builtin(name = "a2b_hex", minNumOfPositionalArgs = 2, declaresExplicitSelf = true)
122+
@Builtin(name = "a2b_hex", minNumOfPositionalArgs = 1)
140123
@GenerateNodeFactory
141-
abstract static class A2bHexNode extends PythonBinaryBuiltinNode {
142-
@Child private ReadAttributeFromObjectNode readAttrNode;
143-
@Child private RaiseNode raiseNode;
144-
@Child private CallNode callExceptionConstructor;
124+
abstract static class A2bHexNode extends PythonUnaryBuiltinNode {
145125

146126
@Specialization
147127
@TruffleBoundary
148-
PBytes a2b(PythonModule self, String data) {
128+
PBytes a2b(String data) {
149129
int length = data.length();
150130
if (length % 2 != 0) {
151-
throw oddLengthError(self);
131+
throw raise(BinasciiError, ErrorMessages.ODD_LENGTH_STRING);
152132
}
153133
byte[] output = new byte[length / 2];
154134
for (int i = 0; i < length / 2; i++) {
155135
try {
156-
output[i] = (byte) (digitValue(self, data.charAt(i * 2)) * 16 + digitValue(self, data.charAt(i * 2 + 1)));
136+
output[i] = (byte) (digitValue(data.charAt(i * 2)) * 16 + digitValue(data.charAt(i * 2 + 1)));
157137
} catch (NumberFormatException e) {
158-
throw nonHexError(self);
138+
throw raise(BinasciiError, ErrorMessages.NON_HEX_DIGIT_FOUND);
159139
}
160140
}
161141
return factory().createBytes(output);
162142
}
163143

164144
@Specialization(guards = "bufferLib.isBuffer(buffer)", limit = "2")
165-
PBytes a2b(PythonModule self, Object buffer,
145+
PBytes a2b(Object buffer,
166146
@CachedLibrary("buffer") PythonObjectLibrary bufferLib) {
167147
try {
168-
return a2b(self, bufferLib.getBufferBytes(buffer));
148+
return a2b(bufferLib.getBufferBytes(buffer));
169149
} catch (UnsupportedMessageException e) {
170150
throw CompilerDirectives.shouldNotReachHere();
171151
}
172152
}
173153

174154
@TruffleBoundary
175-
private PBytes a2b(PythonModule self, byte[] bytes) {
155+
private PBytes a2b(byte[] bytes) {
176156
int length = bytes.length;
177157
if (length % 2 != 0) {
178-
throw oddLengthError(self);
158+
throw raise(BinasciiError, ErrorMessages.ODD_LENGTH_STRING);
179159
}
180160
byte[] output = new byte[length / 2];
181161
for (int i = 0; i < length / 2; i++) {
182-
output[i] = (byte) (digitValue(self, (char) bytes[i * 2]) * 16 + digitValue(self, (char) bytes[i * 2 + 1]));
162+
output[i] = (byte) (digitValue((char) bytes[i * 2]) * 16 + digitValue((char) bytes[i * 2 + 1]));
183163
}
184164
return factory().createBytes(output);
185165
}
186166

187-
private int digitValue(PythonModule self, char b) {
167+
private int digitValue(char b) {
188168
if (b >= '0' && b <= '9') {
189169
return b - '0';
190170
} else if (b >= 'a' && b <= 'f') {
191171
return b - 'a' + 10;
192172
} else if (b >= 'A' && b <= 'F') {
193173
return b - 'A' + 10;
194174
} else {
195-
throw nonHexError(self);
196-
}
197-
}
198-
199-
private PException oddLengthError(PythonModule self) {
200-
raiseObject(getAttrNode().execute(self, ERROR), ErrorMessages.ODD_LENGTH_STRING);
201-
CompilerDirectives.transferToInterpreterAndInvalidate();
202-
throw new IllegalStateException("should not be reached");
203-
}
204-
205-
private PException nonHexError(PythonModule self) {
206-
raiseObject(getAttrNode().execute(self, ERROR), ErrorMessages.NON_HEX_DIGIT_FOUND);
207-
CompilerDirectives.transferToInterpreterAndInvalidate();
208-
throw new IllegalStateException("should not be reached");
209-
}
210-
211-
private ReadAttributeFromObjectNode getAttrNode() {
212-
if (readAttrNode == null) {
213-
CompilerDirectives.transferToInterpreterAndInvalidate();
214-
readAttrNode = insert(ReadAttributeFromObjectNode.create());
175+
throw raise(BinasciiError, ErrorMessages.NON_HEX_DIGIT_FOUND);
215176
}
216-
return readAttrNode;
217177
}
218178

219-
private void raiseObject(Object exceptionObject, String message) {
220-
if (callExceptionConstructor == null) {
221-
CompilerDirectives.transferToInterpreterAndInvalidate();
222-
callExceptionConstructor = insert(CallNode.create());
223-
}
224-
if (raiseNode == null) {
225-
CompilerDirectives.transferToInterpreterAndInvalidate();
226-
raiseNode = insert(RaiseNodeGen.create(null, null));
227-
}
228-
raiseNode.execute(callExceptionConstructor.execute(exceptionObject, message), PNone.NO_VALUE);
229-
}
230179
}
231180

232181
@Builtin(name = "b2a_base64", minNumOfPositionalArgs = 1, numOfPositionalOnlyArgs = 1, parameterNames = {"data"}, keywordOnlyNames = {"newline"})
233182
@ArgumentClinic(name = "newline", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "1", useDefaultForNone = true)
234183
@GenerateNodeFactory
235184
abstract static class B2aBase64Node extends PythonClinicBuiltinNode {
236185
@TruffleBoundary
237-
private static byte[] b2a(byte[] data, int newline) {
238-
String encode = Base64.encode(data);
186+
private byte[] b2a(byte[] data, int newline) {
187+
byte[] encoded;
188+
try {
189+
encoded = Base64.getEncoder().encode(data);
190+
} catch (IllegalArgumentException e) {
191+
throw raise(BinasciiError, e);
192+
}
239193
if (newline != 0) {
240-
return (encode + "\n").getBytes();
194+
encoded = Arrays.copyOf(encoded, encoded.length + 1);
195+
encoded[encoded.length - 1] = '\n';
241196
}
242-
return encode.getBytes();
197+
return encoded;
243198
}
244199

245200
@Specialization(guards = "bufferLib.isBuffer(data)", limit = "3")
@@ -318,7 +273,7 @@ private static long getCrcValue(byte[] bytes) {
318273
abstract static class HexlifyNode extends B2aHexNode {
319274
}
320275

321-
@Builtin(name = "unhexlify", minNumOfPositionalArgs = 2, declaresExplicitSelf = true)
276+
@Builtin(name = "unhexlify", minNumOfPositionalArgs = 1)
322277
@GenerateNodeFactory
323278
abstract static class UnhexlifyNode extends A2bHexNode {
324279
}

0 commit comments

Comments
 (0)