diff --git a/media/json-binding/src/main/java/org/glassfish/jersey/jsonb/internal/JsonBindingProvider.java b/media/json-binding/src/main/java/org/glassfish/jersey/jsonb/internal/JsonBindingProvider.java index 3d4ad43aa9..3ac8031e87 100644 --- a/media/json-binding/src/main/java/org/glassfish/jersey/jsonb/internal/JsonBindingProvider.java +++ b/media/json-binding/src/main/java/org/glassfish/jersey/jsonb/internal/JsonBindingProvider.java @@ -29,6 +29,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.NoContentException; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; import javax.ws.rs.ext.Providers; @@ -39,6 +40,7 @@ import org.glassfish.jersey.jsonb.LocalizationMessages; import org.glassfish.jersey.message.internal.AbstractMessageReaderWriterProvider; +import org.glassfish.jersey.message.internal.EntityInputStream; /** * Entity provider (reader and writer) for JSONB. @@ -70,7 +72,14 @@ public Object readFrom(Class type, Type genericType, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { + final EntityInputStream entityInputStream = new EntityInputStream(entityStream); + entityStream = entityInputStream; + if (entityInputStream.isEmpty()) { + throw new NoContentException(LocalizationMessages.ERROR_JSONB_EMPTYSTREAM()); + } + Jsonb jsonb = getJsonb(type); + try { return jsonb.fromJson(entityStream, genericType); } catch (JsonbException e) { diff --git a/media/json-binding/src/main/resources/org/glassfish/jersey/jsonb/localization.properties b/media/json-binding/src/main/resources/org/glassfish/jersey/jsonb/localization.properties index c7b5a949d5..4eee493a70 100644 --- a/media/json-binding/src/main/resources/org/glassfish/jersey/jsonb/localization.properties +++ b/media/json-binding/src/main/resources/org/glassfish/jersey/jsonb/localization.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. # # This program and the accompanying materials are made available under the # terms of the Eclipse Public License v. 2.0, which is available at @@ -16,3 +16,4 @@ error.jsonb.serialization=Error writing JSON-B serialized object. error.jsonb.deserialization=Error deserializing object from entity stream. +error.jsonb.emptystream=JSON-B cannot parse empty input stream. diff --git a/media/json-binding/src/test/java/org/glassfish/jersey/jsonb/internal/JsonBindingProviderTest.java b/media/json-binding/src/test/java/org/glassfish/jersey/jsonb/internal/JsonBindingProviderTest.java new file mode 100644 index 0000000000..1a8cf00bc1 --- /dev/null +++ b/media/json-binding/src/test/java/org/glassfish/jersey/jsonb/internal/JsonBindingProviderTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020 Markus KARG + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.jsonb.internal; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.NoContentException; +import javax.ws.rs.ext.ContextResolver; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Providers; + +import org.junit.Test; + +/** + * Unit Test for {@link JsonBindingProvider}. + * + * @author Markus KARG (markus@headcrashing.eu) + */ +public final class JsonBindingProviderTest { + + @Test(expected = NoContentException.class) + public final void shouldThrowNoContentException() throws IOException { + // given + final Providers providers = new EmptyProviders(); + final MessageBodyReader mbr = (MessageBodyReader) new JsonBindingProvider(providers); + + // when + mbr.readFrom(Foo.class, Foo.class, new Annotation[0], APPLICATION_JSON_TYPE, + new MultivaluedHashMap<>(), new ByteArrayInputStream(new byte[0])); + + // then + // should throw NoContentException + } + + private static final class Foo { + // no members + } + + private static final class EmptyProviders implements Providers { + + @Override + public final MessageBodyReader getMessageBodyReader(final Class type, final Type genericType, + final Annotation[] annotations, final MediaType mediaType) { + return null; + } + + @Override + public final MessageBodyWriter getMessageBodyWriter(final Class type, final Type genericType, + final Annotation[] annotations, final MediaType mediaType) { + return null; + } + + @Override + public final ExceptionMapper getExceptionMapper(final Class type) { + return null; + } + + @Override + public final ContextResolver getContextResolver(final Class contextType, final MediaType mediaType) { + return null; + } + + } + +}