Skip to content

Commit 55847b5

Browse files
committed
Return byte[]s for non-UTF-8 file paths.
The watchman docs note that, due to file system APIs being encoding-less, we can't assume the bser strings are UTF-8. This changes the bser string deserializer to fallback to returning a byte[] when UTF-8 deserialization fails. This lets client to a cast/instanceof check on String or byte[] and decide how they want to handle the value.
1 parent f774d52 commit 55847b5

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

java/src/com/facebook/watchman/bser/BserDeserializer.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.nio.ByteOrder;
3131
import java.nio.charset.CharsetDecoder;
3232
import java.nio.charset.CodingErrorAction;
33+
import java.nio.charset.MalformedInputException;
3334
import java.nio.charset.StandardCharsets;
3435

3536
import java.util.ArrayList;
@@ -219,9 +220,10 @@ private Number deserializeNumber(ByteBuffer buffer, byte type) throws IOExceptio
219220
}
220221
}
221222

222-
private String deserializeString(ByteBuffer buffer) throws IOException {
223+
private Object deserializeString(ByteBuffer buffer) throws IOException {
223224
byte intType = buffer.get();
224225
int len = deserializeIntLen(buffer, intType);
226+
int pos = buffer.position();
225227

226228
// We use a CharsetDecoder here instead of String(byte[], Charset)
227229
// because we want it to throw an exception for any non-UTF-8 input.
@@ -234,6 +236,11 @@ private String deserializeString(ByteBuffer buffer) throws IOException {
234236
//
235237
// See: http://java-performance.info/string-intern-in-java-6-7-8/
236238
return utf8Decoder.decode(buffer).toString().intern();
239+
} catch (MalformedInputException notUtf8) {
240+
buffer.position(pos);
241+
byte[] b = new byte[buffer.remaining()];
242+
buffer.get(b);
243+
return b;
237244
} finally {
238245
buffer.limit(buffer.capacity());
239246
}
@@ -272,7 +279,7 @@ private Map<String, Object> deserializeObject(ByteBuffer buffer) throws IOExcept
272279
"Unrecognized BSER object key type %d, expected string",
273280
stringType));
274281
}
275-
String key = deserializeString(buffer);
282+
String key = (String) deserializeString(buffer);
276283
Object value = deserializeRecursive(buffer);
277284
map.put(key, value);
278285
}

0 commit comments

Comments
 (0)