Skip to content

ByteUtils.getBytes(ByteBuffer) does not respect buffer position for heap buffers #2204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hban opened this issue Nov 22, 2021 · 1 comment
Closed
Assignees
Labels
type: regression A regression from a previous release

Comments

@hban
Copy link

hban commented Nov 22, 2021

Noticed after upgrading from 2.5.5 to 2.6.0. If RedisElementWriter returns ByteBuffer that is not completely filled (limit() < capacity()), Spring Data will still use the entire buffer (including trailing junk bytes), instead of using only the filled part. This happens for ZSet values at least, I haven't checked other scenarios.

Reproducer:

import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.serializer.RedisElementReader;
import org.springframework.data.redis.serializer.RedisElementWriter;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import java.nio.ByteBuffer;

public class Foo {
    public static void main(String[] args) {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration);
        connectionFactory.afterPropertiesSet();

        RedisElementReader<Integer> reader = buffer -> { throw new UnsupportedOperationException(); };
        RedisElementWriter<Integer> writer = element -> {
            // Buffer is intentionally larger than necessary.
            ByteBuffer buffer = ByteBuffer.allocate(16);
            buffer.putInt(element);
            buffer.flip();
            System.out.printf("Serialized value (%d) has %d bytes%n", element, buffer.remaining());
            return buffer;
        };

        RedisSerializationContext<Integer, Integer> serializationContext = RedisSerializationContext
                .<Integer, Integer>newSerializationContext()
                .key(reader, writer)
                .value(reader, writer)
                .hashKey(reader, writer)
                .hashValue(reader, writer)
                .build();

        ReactiveRedisTemplate<Integer, Integer> intTemplate =
                new ReactiveRedisTemplate<>(connectionFactory, serializationContext);
        intTemplate.opsForZSet().add(20, 21, 22.0).block();

        ReactiveRedisTemplate<byte[], byte[]> byteTemplate =
                new ReactiveRedisTemplate<>(connectionFactory, RedisSerializationContext.byteArray());
        byteTemplate.opsForZSet()
                .scan(new byte[] { 0, 0, 0, 20 })
                .doOnNext(tuple -> {
                    // This prints "4 bytes" on 2.5.5, but "16 bytes" on 2.6.0.
                    System.out.printf("Deserialized value has %d bytes%n", tuple.getValue().length);
                })
                .then()
                .block();
    }
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 22, 2021
@mp911de mp911de self-assigned this Nov 22, 2021
@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 14, 2021
@mp911de mp911de changed the title ZSet value serialization includes junk bytes ByteUtils.getBytes(ByteBuffer) does not respect buffer position for heap buffers Dec 14, 2021
@mp911de mp911de added type: regression A regression from a previous release and removed type: bug A general bug labels Dec 14, 2021
@mp911de mp911de added this to the 2.6.1 (2021.1.1) milestone Dec 14, 2021
@mp911de
Copy link
Member

mp911de commented Dec 14, 2021

Thanks for reporting the issue. We introduced a regression with Spring Data 2.6 affecting heap buffers.

mp911de added a commit that referenced this issue Dec 14, 2021
We now properly extract the byte array from a ByteBuffer by copying its content respecting the read position and limits.

Closes #2204
mp911de added a commit that referenced this issue Dec 14, 2021
…er).

We now properly extract the byte array from a ByteBuffer by copying its content respecting the read position and limits.

Closes #2204
mp911de added a commit that referenced this issue Dec 14, 2021
…er).

We now properly extract the byte array from a ByteBuffer by copying its content respecting the read position and limits.

Closes #2204
christophstrobl pushed a commit that referenced this issue Dec 15, 2021
…er).

We now properly extract the byte array from a ByteBuffer by copying its content respecting the read position and limits.

Closes #2204
Original Pull Request: #2213
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: regression A regression from a previous release
Projects
None yet
3 participants