Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.

Commit e08a7c8

Browse files
author
Nat Luengnaruemitchai
committed
JERSEY-2837: Correctly handle negative byte values
1 parent 99f34b1 commit e08a7c8

File tree

2 files changed

+88
-89
lines changed

2 files changed

+88
-89
lines changed

core-common/src/main/java/org/glassfish/jersey/internal/util/collection/ByteBufferInputStream.java

Lines changed: 80 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -162,53 +162,16 @@ public int available() throws IOException {
162162

163163
@Override
164164
public int read() throws IOException {
165-
if (eof) {
166-
checkThrowable();
167-
checkNotClosed();
168-
return -1;
169-
}
170-
171-
final int c;
172-
if (current != null && current.hasRemaining()) {
173-
c = current.get();
174-
} else {
175-
try {
176-
// let's block until next non-empty chunk or EOF
177-
c = fetchChunk(true) ? current.get() : -1;
178-
} catch (final InterruptedException e) {
179-
Thread.currentThread().interrupt();
180-
throw new IOException(e);
181-
}
182-
}
183-
184-
checkThrowable();
185-
checkNotClosed();
186-
return c;
165+
return tryRead(true);
187166
}
188167

189168
@Override
190-
public int tryRead() throws IOException {
191-
checkThrowable();
192-
checkNotClosed();
193-
194-
if (eof) {
195-
return -1;
196-
}
197-
198-
if (current != null && current.hasRemaining()) {
199-
return current.get();
200-
}
201-
202-
try {
203-
// try to fetch, but don't block && check if something has been fetched
204-
if (fetchChunk(false) && current != null) {
205-
return current.get();
206-
}
207-
} catch (final InterruptedException e) {
208-
Thread.currentThread().interrupt();
209-
}
169+
public int read(byte[] b, int off, int len) throws IOException {
170+
return tryRead(b, off, len, true);
171+
}
210172

211-
return (eof) ? -1 : NOTHING;
173+
public int tryRead() throws IOException {
174+
return tryRead(false);
212175
}
213176

214177
@Override
@@ -218,44 +181,7 @@ public int tryRead(final byte[] b) throws IOException {
218181

219182
@Override
220183
public int tryRead(final byte[] b, final int off, final int len) throws IOException {
221-
checkThrowable();
222-
checkNotClosed();
223-
224-
if (b == null) {
225-
throw new NullPointerException();
226-
} else if (off < 0 || len < 0 || len > b.length - off) {
227-
throw new IndexOutOfBoundsException();
228-
} else if (len == 0) {
229-
return 0;
230-
}
231-
232-
if (eof) {
233-
return -1;
234-
}
235-
236-
int i = 0;
237-
while (i < len) {
238-
if (current != null && current.hasRemaining()) {
239-
final int available = current.remaining();
240-
if (available < len - i) {
241-
current.get(b, off + i, available);
242-
i += available;
243-
} else {
244-
current.get(b, off + i, len - i);
245-
return len;
246-
}
247-
} else {
248-
try {
249-
if (!fetchChunk(false) || current == null) {
250-
break; // eof or no data
251-
}
252-
} catch (final InterruptedException e) {
253-
Thread.currentThread().interrupt();
254-
}
255-
}
256-
}
257-
258-
return i;
184+
return tryRead(b, off, len, false);
259185
}
260186

261187
@Override
@@ -335,4 +261,77 @@ public void closeQueue(final Throwable throwable) {
335261
}
336262
}
337263
}
264+
265+
private int tryRead(final byte[] b, final int off, final int len, boolean block) throws IOException {
266+
checkThrowable();
267+
checkNotClosed();
268+
269+
if (b == null) {
270+
throw new NullPointerException();
271+
} else if (off < 0 || len < 0 || len > b.length - off) {
272+
throw new IndexOutOfBoundsException();
273+
} else if (len == 0) {
274+
return 0;
275+
}
276+
277+
if (eof) {
278+
return -1;
279+
}
280+
281+
int i = 0;
282+
while (i < len) {
283+
if (current != null && current.hasRemaining()) {
284+
final int available = current.remaining();
285+
if (available < len - i) {
286+
current.get(b, off + i, available);
287+
i += available;
288+
} else {
289+
current.get(b, off + i, len - i);
290+
return len;
291+
}
292+
} else {
293+
try {
294+
if (!fetchChunk(block) || current == null) {
295+
break; // eof or no data
296+
}
297+
} catch (final InterruptedException e) {
298+
Thread.currentThread().interrupt();
299+
if (block) {
300+
throw new IOException(e);
301+
}
302+
}
303+
}
304+
}
305+
306+
return i;
307+
}
308+
309+
private int tryRead(boolean block) throws IOException {
310+
checkThrowable();
311+
checkNotClosed();
312+
313+
if (eof) {
314+
return -1;
315+
}
316+
317+
if (current != null && current.hasRemaining()) {
318+
return current.get() & 0xFF;
319+
}
320+
321+
try {
322+
// try to fetch, but don't block && check if something has been fetched
323+
if (fetchChunk(block) && current != null) {
324+
return current.get() & 0xFF;
325+
} else if (block) {
326+
return -1;
327+
}
328+
} catch (final InterruptedException e) {
329+
Thread.currentThread().interrupt();
330+
if (block) {
331+
throw new IOException(e);
332+
}
333+
}
334+
335+
return (eof) ? -1 : NOTHING;
336+
}
338337
}

core-common/src/test/java/org/glassfish/jersey/internal/util/collection/ByteBufferInputStreamTest.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public void run() {
8585
}
8686
data.clear();
8787
for (int j = 0; j < data.capacity(); j++) {
88-
data.put((byte) (i % 128));
88+
data.put((byte) (i & 0xFF));
8989
}
9090
data.flip();
9191
if (!bbis.put(data)) {
@@ -113,7 +113,7 @@ public void run() {
113113
Thread.yield(); // Give the other thread a chance to run.
114114
continue;
115115
}
116-
assertEquals("At position: " + j, (byte) (i % 128), c);
116+
assertEquals("At position: " + j, (byte) (i & 0xFF), (byte) (c & 0xFF));
117117
if (++j % BUFFER_SIZE == 0) {
118118
i++;
119119
Thread.yield(); // Give the other thread a chance to run.
@@ -155,7 +155,7 @@ public void run() {
155155
}
156156
data.clear();
157157
for (int j = 0; j < data.capacity(); j++) {
158-
data.put((byte) (i % 128));
158+
data.put((byte) (i & 0xFF));
159159
}
160160
data.flip();
161161
if (!bbis.put(data)) {
@@ -185,7 +185,7 @@ public void run() {
185185
continue;
186186
}
187187
for (int p = 0; p < c; p++) {
188-
assertEquals("At position: " + j, (byte) (i % 128), buffer[p]);
188+
assertEquals("At position: " + j, (byte) (i & 0xFF), (byte) buffer[p]);
189189
if (++j % BUFFER_SIZE == 0) {
190190
i++;
191191
Thread.yield(); // Give the other thread a chance to run.
@@ -228,7 +228,7 @@ public void run() {
228228
}
229229
data.clear();
230230
for (int j = 0; j < data.capacity(); j++) {
231-
data.put((byte) (i % 128));
231+
data.put((byte) (i & 0xFF));
232232
}
233233
data.flip();
234234
if (!bbis.put(data)) {
@@ -253,7 +253,7 @@ public void run() {
253253
while ((c = bbis.read()) != -1) {
254254
assertNotEquals("Should not read 'nothing' in blocking mode.", Integer.MIN_VALUE, c);
255255

256-
assertEquals("At position: " + j, (byte) (i % 128), c);
256+
assertEquals("At position: " + j, (byte) (i & 0xFF), (byte) c);
257257
if (++j % BUFFER_SIZE == 0) {
258258
i++;
259259
Thread.yield(); // Give the other thread a chance to run.
@@ -295,7 +295,7 @@ public void run() {
295295
}
296296
data.clear();
297297
for (int j = 0; j < data.capacity(); j++) {
298-
data.put((byte) (i % 128));
298+
data.put((byte) (i & 0xFF));
299299
}
300300
data.flip();
301301
if (!bbis.put(data)) {
@@ -322,7 +322,7 @@ public void run() {
322322
assertNotEquals("Should not read 0 bytes in blocking mode.", 0, c);
323323

324324
for (int p = 0; p < c; p++) {
325-
assertEquals("At position: " + j, (byte) (i % 128), buffer[p]);
325+
assertEquals("At position: " + j, (byte) (i & 0xFF), buffer[p]);
326326
if (++j % BUFFER_SIZE == 0) {
327327
i++;
328328
Thread.yield(); // Give the other thread a chance to run.

0 commit comments

Comments
 (0)