protocolbuffers / protocolbuffers/protobuf

bug: CodedInputStream.newInstance(List) with an empty bytebuffer produces an error

Open
#23,957 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

help wanted java
Dominant language
C++
Stars
72k
Forks
16.3k
Avg merge
1d 17h
Merged PRs (30d)
140

Description

What version of protobuf and what language are you using?
Language: Java: originally found in 3.25.4, still present in 4.33.0-RC2

What operating system (Linux, Windows, ...) and version?
Tested MacOS 15.6.1, Linux 5.14.0

What runtime / compiler are you using (e.g., python version or gcc version)
N/A

What did you do?
Steps to reproduce the behavior:

  1. Create a CodedInputStream with an empty list
  2. Confirm that readTag() returns 0
  3. Create a CodedInputStream with a single empty ByteBuffer
  4. Call readTag()
import com.google.protobuf.CodedInputStream
import java.nio.ByteBuffer
import java.util.List

public class App {
  public static void main(String[] args) {
    CodedInputStream cis = CodedInputStream.newInstance(List.of())
    System.out.println(cis.readTag());//success, returns 0

    cis = CodedInputStream.newInstance(List.of(ByteBuffer.wrap(new byte[0])));
    System.out.println(cis.readTag());//failure, throws exception
  }
}

What did you expect to see
Should return zero, same as readTag() for an empty list

What did you see instead?

Exception java.lang.IllegalStateException: class com.google.protobuf.IterableByteBufferInputStream#read(byte[]) returned invalid result: 0
The InputStream implementation is buggy.
      at CodedInputStream$StreamDecoder.tryRefillBuffer (CodedInputStream.java:2882)
      at CodedInputStream$StreamDecoder.isAtEnd (CodedInputStream.java:2794)
      at CodedInputStream$StreamDecoder.readTag (CodedInputStream.java:2151)

Note that empty ByteBuffers within a larger collection do not seem to cause a problem with some quick testing, just a collection with only empty ByteBuffers in it.

CodedInputStream cis = CodedInputStream.newInstance(List.of(ByteBuffer.allocate(0), ByteBuffer.wrap(new byte[]{0x0a}), ByteBuffer.wrap(new byte[]{0x01, 0x61})))
System.out.println(cis.readTag());// success
System.out.println(cis.readString());

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the Java example with CodedInputStream.newInstance(List.of(ByteBuffer.wrap(new byte[0]))), then inspect CodedInputStream.java around StreamDecoder.tryRefillBuffer and isAtEnd, along with IterableByteBufferInputStream. Done means readTag() returns 0 for a collection containing only empty ByteBuffers without throwing the invalid-result exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.