diff --git a/lang/perl/lib/Avro/BinaryDecoder.pm b/lang/perl/lib/Avro/BinaryDecoder.pm index d2bb65e14f7..76fc7a8ec34 100644 --- a/lang/perl/lib/Avro/BinaryDecoder.pm +++ b/lang/perl/lib/Avro/BinaryDecoder.pm @@ -22,6 +22,7 @@ use warnings; use Config; use Encode(); use Error::Simple; +use Fcntl(); use Avro::Schema; our $VERSION = '++MODULE_VERSION++'; @@ -124,7 +125,7 @@ sub skip_bytes { my $class = shift; my $reader = pop; my $size = decode_long($class, undef, undef, $reader); - $reader->seek($size, 0); + $reader->seek($size, Fcntl->SEEK_CUR); return; } @@ -350,7 +351,7 @@ sub decode_union { sub skip_fixed { my $class = shift; my ($schema, $reader) = @_; - $reader->seek($schema->size, 0); + $reader->seek($schema->size, Fcntl->SEEK_CUR); } ## 1.3.2 Fixed instances are encoded using the number of bytes declared in the diff --git a/lang/perl/t/03_bin_decode.t b/lang/perl/t/03_bin_decode.t index e5da35d9983..8c6c2d47544 100644 --- a/lang/perl/t/03_bin_decode.t +++ b/lang/perl/t/03_bin_decode.t @@ -170,6 +170,63 @@ EOJ } "Avro::Schema::Error::Mismatch", "no default value!"; } +## skipping a writer field must advance relative to the current position, so a +## field that follows a skipped bytes/string/fixed field still decodes correctly +{ + my $w_schema = Avro::Schema->parse(<parse(<encode( + schema => $w_schema, + data => { skipped => "hello", keep => 42 }, + emit_cb => sub { $enc .= ${ $_[0] } }, + ); + open my $reader, '<', \$enc or die "Cannot open memory file: $!"; + my $dec = Avro::BinaryDecoder->decode( + writer_schema => $w_schema, + reader_schema => $r_schema, + reader => $reader, + ); + is $dec->{keep}, 42, "field after a skipped bytes field decodes correctly"; + + my $wf_schema = Avro::Schema->parse(<parse(<encode( + schema => $wf_schema, + data => { before => 9, skipped => "abcd", keep => 7 }, + emit_cb => sub { $enc .= ${ $_[0] } }, + ); + open $reader, '<', \$enc or die "Cannot open memory file: $!"; + $dec = Avro::BinaryDecoder->decode( + writer_schema => $wf_schema, + reader_schema => $rf_schema, + reader => $reader, + ); + is $dec->{before}, 9, "field before a skipped fixed field decodes correctly"; + is $dec->{keep}, 7, "field after a skipped fixed field decodes correctly"; +} + ## union resolution { my $w_schema = Avro::Schema->parse(<