提交 fd0213b7 编写于 作者: J Jake Wharton

Skip a UTF-8 BOM if present.

上级 9f00bd30
......@@ -23,6 +23,12 @@
<groupId>com.squareup.moshi</groupId>
<artifactId>moshi</artifactId>
</dependency>
<!-- TODO remove this dependency once Moshi or OkHttp ships with 1.9.0 or newer. -->
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
......
......@@ -18,9 +18,13 @@ package retrofit2.converter.moshi;
import com.squareup.moshi.JsonAdapter;
import java.io.IOException;
import okhttp3.ResponseBody;
import okio.BufferedSource;
import okio.ByteString;
import retrofit2.Converter;
final class MoshiResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private static final ByteString UTF8_BOM = ByteString.decodeHex("EFBBBF");
private final JsonAdapter<T> adapter;
MoshiResponseBodyConverter(JsonAdapter<T> adapter) {
......@@ -28,8 +32,14 @@ final class MoshiResponseBodyConverter<T> implements Converter<ResponseBody, T>
}
@Override public T convert(ResponseBody value) throws IOException {
BufferedSource source = value.source();
try {
return adapter.fromJson(value.source());
// Moshi has no document-level API so the responsibility of BOM skipping falls to whatever
// is delegating to it. Since it's a UTF-8-only library as well we only honor the UTF-8 BOM.
if (source.rangeEquals(0, UTF8_BOM)) {
source.skip(UTF8_BOM.size());
}
return adapter.fromJson(source);
} finally {
value.close();
}
......
......@@ -26,10 +26,13 @@ import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.Set;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import okio.Buffer;
import okio.ByteString;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
......@@ -203,4 +206,32 @@ public final class MoshiConverterFactoryTest {
AnImplementation body = response.body();
assertThat(body.theName).isEqualTo("value");
}
@Test public void utf8BomSkipped() throws IOException {
Buffer responseBody = new Buffer()
.write(ByteString.decodeHex("EFBBBF"))
.writeUtf8("{\"theName\":\"value\"}");
MockResponse malformedResponse = new MockResponse().setBody(responseBody);
server.enqueue(malformedResponse);
Call<AnImplementation> call = service.anImplementation(new AnImplementation("value"));
Response<AnImplementation> response = call.execute();
AnImplementation body = response.body();
assertThat(body.theName).isEqualTo("value");
}
@Test public void nonUtf8BomIsNotSkipped() throws IOException {
Buffer responseBody = new Buffer()
.write(ByteString.decodeHex("FEFF"))
.writeString("{\"theName\":\"value\"}", Charset.forName("UTF-16"));
MockResponse malformedResponse = new MockResponse().setBody(responseBody);
server.enqueue(malformedResponse);
Call<AnImplementation> call = service.anImplementation(new AnImplementation("value"));
try {
call.execute();
fail();
} catch (IOException expected) {
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册