Nik Clayton created THRIFT-5131:
-----------------------------------
Summary: i64 maxint decoding panics with integer-encoding >= 1.1.0
Key: THRIFT-5131
URL: https://issues.apache.org/jira/browse/THRIFT-5131
Project: Thrift
Issue Type: Bug
Components: Rust - Library
Affects Versions: 0.13.0
Environment: % cargo --version --verbose
cargo 1.40.0
release: 1.40.0
% uname -a
Darwin Niks-MacBook-Pro.local 19.3.0 Darwin Kernel Version 19.3.0: Thu Jan 9
20:58:23 PST 2020; root:xnu-6153.81.5~1/RELEASE_X86_64 x86_64 i386
MacBookPro15,1 Darwin
Reporter: Nik Clayton
The Rust library for Thrift uses the integer-encoding crate. In version 1.1.0
(through at least 1.1.3, the most recent version) of this crate Thrift's usage
appears to be responsible for a panic in the library when trying to decode i64
numbers in the range 0x4000_0000_0000_0000 to 0x7FFF_FFFF_FFFF_FFFF.
The integer-encoding crate does not panic when using it directly to encode /
decode numbers in this range.
To see this, create a scratch crate with "cargo new int_encoding".
Replace the contents of Cargo.toml with the following:
{code}
[package]
name = "int_encoding"
version = "0.1.0"
authors = ["Nik Clayton <[email protected]>"]
edition = "2018"
[dependencies]
thrift = "0.13.0"
integer-encoding = "=1.0.8"
{code}
This pins the integer-encoding library to version 1.0.8.
Put the following in src/main.rs:
{code}
use thrift::protocol::{
TCompactInputProtocol, TCompactOutputProtocol, TFieldIdentifier,
TInputProtocol,
TOutputProtocol, TType,
};
use integer_encoding::*;
fn main() {
let mut field_value = i64::max_value(); // Fails
// Uncomment the next line to see success
//field_value = (1i64 << 62) - 1;
let mut buf;
println!("Value is: {}, {:X}", field_value, field_value);
// First check that encoding and decoding works using the integer_encoding
// library directly.
buf = field_value.encode_var_vec();
let (val, _) = VarInt::decode_var(&buf[..]);
assert_eq!(field_value, val);
// Clear the buffer, and try encoding the same value using Thrift. This code
// is almost identical to
https://docs.rs/thrift/0.13.0/thrift/protocol/index.html
// except that (a) it's an I64, and (b) the channel is a Vec.
buf.clear();
let mut out_protocol = TCompactOutputProtocol::new(&mut buf);
out_protocol
.write_field_begin(&TFieldIdentifier::new(
"max_int",
TType::I64,
1,
))
.unwrap();
out_protocol.write_i64(field_value).unwrap();
out_protocol.write_field_end().unwrap();
out_protocol.flush().unwrap();
let mut in_protocol = TCompactInputProtocol::new(&buf[..]);
in_protocol.read_field_begin().unwrap();
assert_eq!(field_value, in_protocol.read_i64().unwrap());
in_protocol.read_field_end().unwrap();
}
{code}
Run this with "cargo run", it should succeed, and print:
{code}
Value is: 9223372036854775807, 7FFFFFFFFFFFFFFF
{code}
Edit Cargo.toml and change the "integer-encoding" line to
{code}
integer-encoding = "=1.1.3"
{code}
Run with "RUST_BACKTRACE=1 cargo run" and you will see the following panic
(I've elided the full panic here):
{code}
thread 'main' panicked at 'index 11 out of range for slice of length 10',
src/libcore/slice/mod.rs:2664:5
stack backtrace:
[...]
13: integer_encoding::reader::VarIntProcessor::decode
at
/Users/nik/d/rs/.cargo-home/registry/src/github.com-1ecc6299db9ec823/integer-encoding-1.1.3/src/reader.rs:56
14: <R as integer_encoding::reader::VarIntReader>::read_varint
at
/Users/nik/d/rs/.cargo-home/registry/src/github.com-1ecc6299db9ec823/integer-encoding-1.1.3/src/reader.rs:104
15: <thrift::protocol::compact::TCompactInputProtocol<T> as
thrift::protocol::TInputProtocol>::read_i64
at
/Users/nik/d/rs/.cargo-home/registry/src/github.com-1ecc6299db9ec823/thrift-0.13.0/src/protocol/compact.rs:246
16: int_encoding::main
at src/main.rs:41
[...]
{code}
As you can see, the panic is coming from the call to Thrift's read_i64(). The
earlier code that used integer-encoding directly did not panic. That's why I
think the problem is somewhere in Thrift.
If you edit main.rs and uncomment the line
{code}
//field_value = (1i64 << 62) - 1;
{code}
the panic disappears. I believe this is the largest number that can be used
without triggering the panic.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)