apache / apache/servicecomb-java-chassis

[BUG] - Issue Title cse 2.8.20版本 org.apache.servicecomb.foundation.vertx.stream.BufferInputStream流 int read()方法读取单字节,如果读取到流末尾会抛异常IndexOutOfBoundsException

Aperta
#4,778 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub
bug
Lingua principale
Java
Stelle
1.9k
Fork
814
Merge medio
8g 23h
PR unite (30g)
1

Descrizione

### Steps to Reproduce

cse 2.8.20版本 org.apache.servicecomb.foundation.vertx.stream.BufferInputStream流 int read()方法读取单字节,如果读取到流末尾会抛异常IndexOutOfBoundsException

示例代码1: 单独构造失败用例

```
public class CseBufferInputStream {
public static void main(String[] args) throws IOException {
byte[] byteArray = new byte[10];

BufferedReader br = null;
try {
// 由于StsCseServerFilter要在此Filter之前执行,所以,需要重置码流,将ridx置0
InputStream inputStream = getRealInputStream(byteArray);
if (inputStream == null) {
return;
}
inputStream.reset();
while (inputStream.read() >= 0) {
;
}
} finally {
IOUtils.closeQuietly(br);
}
}

public static InputStream getRealInputStream(byte[] byteArray) {
// 创建 UnpooledSlicedByteBuf
ByteBuf slicedByteBuf = Unpooled.wrappedBuffer(byteArray);
// 创建 BufferInputStream,这个stream类型,以及里面的Buffer和真实的走CSE请求的一致
InputStream inputStream = new BufferInputStream(slicedByteBuf);
return inputStream;
}
}
```

直接执行CseBufferInputStream.main()

运行结果
org.apache.servicecomb.foundation.vertx.stream.BufferInputStream流 int read()方法读取单字节,如果读取到流末尾会抛异常IndexOutOfBoundsException

![Image](https://github.com/user-attachments/assets/5c74c3eb-00cb-4a26-a4b7-7cdf90cbabcd)

示例代码2: 实际应用

/**
* gzip解压
* @param byteArray gzip压缩数据
*
* @throws IOException IOException
*/
public static void gzipRead(byte[] byteArray) throws IOException {
BufferedReader br = null;
try {
// 由于StsCseServerFilter要在此Filter之前执行,所以,需要重置码流,将ridx置0
InputStream inputStream = getRealInputStream(byteArray);
if (inputStream == null) {
return;
}
inputStream.reset();

br = new BufferedReader(new InputStreamReader(new GZIPInputStream(inputStream), "UTF-8"));
char[] readBuff = new char[2048];
while ((br.read(readBuff)) > 0) {
}
} finally {
IOUtils.closeQuietly(br);
}
}

public static InputStream getRealInputStream(byte[] byteArray) {
// 创建 UnpooledSlicedByteBuf
ByteBuf slicedByteBuf = Unpooled.wrappedBuffer(byteArray);
// 创建 BufferInputStream,这个stream类型,以及里面的Buffer和真实的走CSE请求的一致
InputStream inputStream = new BufferInputStream(slicedByteBuf);
return inputStream;
}

调用gzipRead方法,传一个正确的gzip压缩二进制流进去, 在 java 1.8.0_432 会报错,其现象和原因同 示例1一致,
int read()方法读取单字节,如果读取到流末尾会抛异常IndexOutOfBoundsException

详细调用链见图 java 1.8.0_432 见红色流程。

![Image](https://github.com/user-attachments/assets/a05c9926-b1f7-4e9d-84d6-c2c4e2a0c864)

### Expected Behavior

org.apache.servicecomb.foundation.vertx.stream.BufferInputStream流 实现 java.io.InputStream
没字节的时候 应该返回-1,接口定义如下
![Image](https://github.com/user-attachments/assets/fc576169-c9f3-483f-8ebd-09b860954e54)

### Servicecomb Version

2.8.20

### Additional Context

_No response_

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Direzione di ricerca

Iniziare con org.apache.servicecomb.foundation.vertx.stream.BufferInputStream e riprodurre il problema utilizzando l'esempio CseBufferInputStream.main. Verificare il comportamento di int read() quando il ByteBuf sottostante raggiunge la fine, quindi verificare che gzipRead con dati gzip validi termini anch'esso senza IndexOutOfBoundsException e che la fine del flusso restituisca -1.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
java
Ambito
backend
Tipo di issue
Bug
Difficoltà
2/5
Tempo stimato
1-3 ore
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
45/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.