Skip to content

Commit e612013

Browse files
authored
Merge 529bb6c into ec26a52
2 parents ec26a52 + 529bb6c commit e612013

File tree

3 files changed

+52
-20
lines changed

3 files changed

+52
-20
lines changed

firebase-perf/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Unreleased
22
* [changed] Updated `protolite-well-known-types` dependency to `18.0.1`. [#6716]
3+
* [fixed] Fixed a bug that allowed invalid payload bytes value in network request metrics.
34

45

56
# 21.0.4

firebase-perf/src/main/java/com/google/firebase/perf/network/InstrHttpInputStream.java

+22-15
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,7 @@ public final class InstrHttpInputStream extends InputStream {
3030
private long timeToResponseInitiated;
3131
private long timeToResponseLastRead = -1;
3232

33-
/**
34-
* Instrumented inputStream object
35-
*
36-
* @param inputStream
37-
* @param builder
38-
* @param timer
39-
*/
33+
/** Instrumented inputStream object */
4034
public InstrHttpInputStream(
4135
final InputStream inputStream, final NetworkRequestMetricBuilder builder, Timer timer) {
4236
this.timer = timer;
@@ -99,12 +93,13 @@ public int read() throws IOException {
9993
if (timeToResponseInitiated == -1) {
10094
timeToResponseInitiated = tempTime;
10195
}
102-
if (bytesRead == -1 && timeToResponseLastRead == -1) {
96+
boolean endOfStream = bytesRead == -1;
97+
if (endOfStream && timeToResponseLastRead == -1) {
10398
timeToResponseLastRead = tempTime;
10499
networkMetricBuilder.setTimeToResponseCompletedMicros(timeToResponseLastRead);
105100
networkMetricBuilder.build();
106101
} else {
107-
this.bytesRead++;
102+
incrementBytesRead(1);
108103
networkMetricBuilder.setResponsePayloadBytes(this.bytesRead);
109104
}
110105
return bytesRead;
@@ -124,12 +119,13 @@ public int read(final byte[] buffer, final int byteOffset, final int byteCount)
124119
if (timeToResponseInitiated == -1) {
125120
timeToResponseInitiated = tempTime;
126121
}
127-
if (bytesRead == -1 && timeToResponseLastRead == -1) {
122+
boolean endOfStream = bytesRead == -1;
123+
if (endOfStream && timeToResponseLastRead == -1) {
128124
timeToResponseLastRead = tempTime;
129125
networkMetricBuilder.setTimeToResponseCompletedMicros(timeToResponseLastRead);
130126
networkMetricBuilder.build();
131127
} else {
132-
this.bytesRead += bytesRead;
128+
incrementBytesRead(bytesRead);
133129
networkMetricBuilder.setResponsePayloadBytes(this.bytesRead);
134130
}
135131
return bytesRead;
@@ -148,12 +144,13 @@ public int read(final byte[] buffer) throws IOException {
148144
if (timeToResponseInitiated == -1) {
149145
timeToResponseInitiated = tempTime;
150146
}
151-
if (bytesRead == -1 && timeToResponseLastRead == -1) {
147+
boolean endOfStream = bytesRead == -1;
148+
if (endOfStream && timeToResponseLastRead == -1) {
152149
timeToResponseLastRead = tempTime;
153150
networkMetricBuilder.setTimeToResponseCompletedMicros(timeToResponseLastRead);
154151
networkMetricBuilder.build();
155152
} else {
156-
this.bytesRead += bytesRead;
153+
incrementBytesRead(bytesRead);
157154
networkMetricBuilder.setResponsePayloadBytes(this.bytesRead);
158155
}
159156
return bytesRead;
@@ -183,11 +180,13 @@ public long skip(final long byteCount) throws IOException {
183180
if (timeToResponseInitiated == -1) {
184181
timeToResponseInitiated = tempTime;
185182
}
186-
if (skipped == -1 && timeToResponseLastRead == -1) {
183+
// InputStream.skip will return 0 for both end of stream and for 0 bytes skipped.
184+
boolean endOfStream = (skipped == 0 && byteCount != 0);
185+
if (endOfStream && timeToResponseLastRead == -1) {
187186
timeToResponseLastRead = tempTime;
188187
networkMetricBuilder.setTimeToResponseCompletedMicros(timeToResponseLastRead);
189188
} else {
190-
bytesRead += skipped;
189+
incrementBytesRead(skipped);
191190
networkMetricBuilder.setResponsePayloadBytes(bytesRead);
192191
}
193192
return skipped;
@@ -197,4 +196,12 @@ public long skip(final long byteCount) throws IOException {
197196
throw e;
198197
}
199198
}
199+
200+
private void incrementBytesRead(long bytesRead) {
201+
if (this.bytesRead == -1) {
202+
this.bytesRead = bytesRead;
203+
} else {
204+
this.bytesRead += bytesRead;
205+
}
206+
}
200207
}

firebase-perf/src/test/java/com/google/firebase/perf/network/InstrHttpInputStreamTest.java

+29-5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.google.firebase.perf.v1.NetworkRequestMetric.NetworkClientErrorReason;
3131
import java.io.IOException;
3232
import java.io.InputStream;
33+
import org.junit.After;
3334
import org.junit.Before;
3435
import org.junit.Test;
3536
import org.junit.runner.RunWith;
@@ -40,10 +41,14 @@
4041
import org.mockito.MockitoAnnotations;
4142
import org.robolectric.RobolectricTestRunner;
4243

43-
/** Unit tests for {@link com.google.firebase.perf.network.InstrHttpInputStream}. */
44+
/**
45+
* Unit tests for {@link com.google.firebase.perf.network.InstrHttpInputStream}.
46+
*
47+
* @noinspection ResultOfMethodCallIgnored
48+
*/
4449
@RunWith(RobolectricTestRunner.class)
4550
public class InstrHttpInputStreamTest extends FirebasePerformanceTestBase {
46-
51+
private AutoCloseable closeable;
4752
@Mock InputStream mInputStream;
4853
@Mock TransportManager transportManager;
4954
@Mock Timer timer;
@@ -53,12 +58,17 @@ public class InstrHttpInputStreamTest extends FirebasePerformanceTestBase {
5358

5459
@Before
5560
public void setUp() {
56-
MockitoAnnotations.initMocks(this);
61+
closeable = MockitoAnnotations.openMocks(this);
5762
when(timer.getMicros()).thenReturn((long) 1000);
5863
when(timer.getDurationMicros()).thenReturn((long) 2000);
5964
networkMetricBuilder = NetworkRequestMetricBuilder.builder(transportManager);
6065
}
6166

67+
@After
68+
public void releaseMocks() throws Exception {
69+
closeable.close();
70+
}
71+
6272
@Test
6373
public void testAvailable() throws IOException {
6474
int availableVal = 7;
@@ -80,7 +90,7 @@ public void testClose() throws IOException {
8090
}
8191

8292
@Test
83-
public void testMark() throws IOException {
93+
public void testMark() {
8494
int markInput = 256;
8595

8696
new InstrHttpInputStream(mInputStream, networkMetricBuilder, timer).mark(markInput);
@@ -89,7 +99,7 @@ public void testMark() throws IOException {
8999
}
90100

91101
@Test
92-
public void testMarkSupported() throws IOException {
102+
public void testMarkSupported() {
93103
when(mInputStream.markSupported()).thenReturn(true);
94104
boolean ret =
95105
new InstrHttpInputStream(mInputStream, networkMetricBuilder, timer).markSupported();
@@ -108,6 +118,20 @@ public void testRead() throws IOException {
108118
verify(mInputStream).read();
109119
}
110120

121+
@Test
122+
public void testReadBufferOffsetZero() throws IOException {
123+
byte[] b = new byte[0];
124+
int off = 0;
125+
int len = 0;
126+
when(mInputStream.read(b, off, len)).thenReturn(len);
127+
int ret = new InstrHttpInputStream(mInputStream, networkMetricBuilder, timer).read(b, off, len);
128+
129+
NetworkRequestMetric metric = networkMetricBuilder.build();
130+
assertThat(ret).isEqualTo(0);
131+
assertThat(metric.getResponsePayloadBytes()).isEqualTo(0);
132+
verify(mInputStream).read(b, off, len);
133+
}
134+
111135
@Test
112136
public void testReadBufferOffsetCount() throws IOException {
113137
byte[] buffer = new byte[] {(byte) 0xe0};

0 commit comments

Comments
 (0)