Skip to content

ChecksumResultset UTF-8 parsing infinite loops #13440

@Noremac201

Description

@Noremac201

Issue Details

Querying single-character UTF-8 characters where the Java String length < byte requirements causes an infinite loop in the Spanner JDBC driver.

The current implementation works for longer strings, but due to how java nio processes buffers, can fail with some inputs that are valid in Cloud Spanner, such as 主键

Example

Setting a STRING column in Cloud Spanner to 主键, then attempting to query it via java-spanner libraries will result in an infinite loop.

Logs and Stack Trace

  351 Thread 0x763e30848
  352   at sun.nio.cs.UTF_8$Encoder.encodeLoop(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult; (UTF_8.java:693)^M
  353   at java.nio.charset.CharsetEncoder.encode(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;Z)Ljava/nio/charset/CoderResult; (CharsetEncoder.java:579)^M
  354   at com.google.cloud.spanner.connection.ChecksumResultSet$ChecksumCalculator.putString(Ljava/lang/String;)V (ChecksumResultSet.java:347)^M
  355   at com.google.cloud.spanner.connection.ChecksumResultSet$ChecksumCalculator.pushValue(Lcom/google/cloud/spanner/Type;Lcom/google/cloud/spanner/jdbc/shaded/com/google/protobuf/Value;)V (ChecksumResultSet.java:277)^M
  356   at com.google.cloud.spanner.connection.ChecksumResultSet$ChecksumCalculator.calculateNextChecksum(Lcom/google/cloud/spanner/ProtobufResultSet;)V (ChecksumResultSet.java:249)^M
  357   at com.google.cloud.spanner.connection.ChecksumResultSet$ChecksumCalculator.access$400(Lcom/google/cloud/spanner/connection/ChecksumResultSet$ChecksumCalculator;Lcom/google/cloud/spanner/ProtobufResultSet;)V (ChecksumResultSet.java:203)^M
  358   at com.google.cloud.spanner.connection.ChecksumResultSet$NextCallable.call()Ljava/lang/Boolean; (ChecksumResultSet.java:112)^M
  359   at com.google.cloud.spanner.connection.ChecksumResultSet$NextCallable.call()Ljava/lang/Object; (ChecksumResultSet.java:102)^M
  360   at com.google.cloud.spanner.connection.ReadWriteTransaction.runWithRetry(Ljava/util/concurrent/Callable;)Ljava/lang/Object; (ReadWriteTransaction.java:965)^M
  361   at com.google.cloud.spanner.connection.ChecksumResultSet.next()Z (ChecksumResultSet.java:124)^M
  362   at com.google.cloud.spanner.jdbc.JdbcResultSet.next()Z (JdbcResultSet.java:178)^M

I will contribute a fix for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions