Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ jobs:
runs-on: ubuntu-24.04
timeout-minutes: 60
env:
TOOLCHAIN_VERSION: 1.85.1
TOOLCHAIN_VERSION: 1.99.0
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
15 changes: 6 additions & 9 deletions .github/workflows/release_rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,14 @@ jobs:
with:
persist-credentials: false

- name: Install Rust 1.85
# The repo-pinned toolchain (rust-toolchain: 1.83) predates edition2024 support
# required by transitive dependencies (getrandom >= 0.4); 1.85 is the minimum
# that passes. Pin explicitly for reproducibility.
run: rustup toolchain install 1.85 --profile minimal
- name: Install Rust 1.99.0
run: rustup toolchain install 1.99.0 --profile minimal

- name: Dry run
working-directory: lib/rs
run: cargo publish --dry-run
env:
RUSTUP_TOOLCHAIN: "1.85"
RUSTUP_TOOLCHAIN: "1.99.0"

publish:
runs-on: ubuntu-latest
Expand All @@ -75,8 +72,8 @@ jobs:
fi
echo "Version check passed: $CRATE_VERSION"

- name: Install Rust 1.85
run: rustup toolchain install 1.85 --profile minimal
- name: Install Rust 1.99.0
run: rustup toolchain install 1.99.0 --profile minimal

- name: Authenticate to crates.io
id: crates-io-auth
Expand All @@ -86,5 +83,5 @@ jobs:
working-directory: lib/rs
run: cargo publish
env:
RUSTUP_TOOLCHAIN: "1.85"
RUSTUP_TOOLCHAIN: "1.99.0"
CARGO_REGISTRY_TOKEN: ${{ steps.crates-io-auth.outputs.token }}
2 changes: 1 addition & 1 deletion LANGUAGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ language; it is the effective minimum the project stands behind for that release
<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/rs/README.md">Rust</a></td>
<!-- Since -----------------><td>0.11.0</td>
<!-- Build Systems ---------><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>1.83.0</td><td>1.85.1</td>
<!-- Language Levels -------><td>1.85.0</td><td>1.99.0</td>
<!-- Field types -----------><td><img src="/doc/images/cgrn.png" alt="Yes"/></td>
<!-- Low-Level Transports --><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td>
<!-- Transport Wrappers ----><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td>
Expand Down
2 changes: 1 addition & 1 deletion build/docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,5 @@ Last updated: May 2, 2026
| php | 8.2 (ondrej) | 8.3 | jammy pulls 8.2 from ppa:ondrej/php |
| python3 | 3.10.12 | | |
| ruby | 3.0.2p107 | | |
| rust | 1.83.0 | | |
| rust | 1.99.0 | | |
| smalltalk | | | Not in CI |
2 changes: 1 addition & 1 deletion build/docker/ubuntu-jammy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ RUN apt-get install -y --no-install-recommends \

USER ${user}
RUN `# Rust dependencies` \
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.83.0 -y
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.99.0 -y
ENV PATH=/home/${user}/.cargo/bin:$PATH
USER root

Expand Down
2 changes: 1 addition & 1 deletion build/docker/ubuntu-noble/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ RUN apt-get install -y --no-install-recommends \

USER ${user}
RUN `# Rust dependencies` \
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.83.0 -y
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.99.0 -y
ENV PATH=/home/${user}/.cargo/bin:$PATH
USER root

Expand Down
11 changes: 5 additions & 6 deletions compiler/cpp/src/thrift/generate/t_rs_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1302,10 +1302,9 @@ void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) {
string field_name("self." + rust_field_name(tfield));
string branch_statement = rendered_branch_count == 0 ? "if" : "} else if";

f_gen_ << indent() << branch_statement << " " << field_name << ".is_some() {" << '\n';
f_gen_ << indent() << branch_statement << " let Some(e) = " << field_name << " {" << '\n';
indent_up();
f_gen_ << indent() << "Err(thrift::Error::User(Box::new(" << field_name << ".unwrap())))"
<< '\n';
f_gen_ << indent() << "Err(thrift::Error::User(Box::new(e)))" << '\n';
indent_down();

rendered_branch_count++;
Expand All @@ -1329,10 +1328,10 @@ void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) {
}
} else {
string branch_statement = rendered_branch_count == 0 ? "if" : "} else if";
f_gen_ << indent() << branch_statement << " self." << SERVICE_RESULT_VARIABLE << ".is_some() {"
<< '\n';
f_gen_ << indent() << branch_statement << " let Some(r) = self." << SERVICE_RESULT_VARIABLE
<< " {" << '\n';
indent_up();
f_gen_ << indent() << "Ok(self." << SERVICE_RESULT_VARIABLE << ".unwrap())" << '\n';
f_gen_ << indent() << "Ok(r)" << '\n';
indent_down();
f_gen_ << indent() << "} else {" << '\n';
indent_up();
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_LIBTOOL

Check warning on line 87 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-js

The macro `AC_PROG_LIBTOOL' is obsolete.

Check warning on line 87 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-java-kotlin

The macro `AC_PROG_LIBTOOL' is obsolete.
AC_PROG_MAKE_SET
AC_PROG_BISON(2.5)
AC_PROG_YACC
AC_PROG_LEX

Check warning on line 91 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-js

AC_PROG_LEX without either yywrap or noyywrap is obsolete

Check warning on line 91 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-java-kotlin

AC_PROG_LEX without either yywrap or noyywrap is obsolete
AM_PROG_LEX
AC_PROG_LN_S
AC_PROG_MKDIR_P
Expand Down Expand Up @@ -162,7 +162,7 @@
AX_LIB_EVENT([2.0])
have_libevent=$success

AX_LIB_ZLIB([1.2.3])

Check warning on line 165 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-js

The macro `AC_PROG_LIBTOOL' is obsolete.

Check warning on line 165 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-java-kotlin

The macro `AC_PROG_LIBTOOL' is obsolete.
have_zlib=$success

AX_THRIFT_LIB(qt5, [Qt5], yes)
Expand Down Expand Up @@ -446,7 +446,7 @@
AC_PATH_PROG([CARGO], [cargo])
AC_PATH_PROG([RUSTC], [rustc])
if [[ -x "$CARGO" ]] && [[ -x "$RUSTC" ]]; then
min_rustc_version="1.13"
min_rustc_version="1.85"

AC_MSG_CHECKING([for rustc version])
rustc_version=`$RUSTC --version 2>&1 | $SED -n -e 's/^rustc \(@<:@0-9@:>@@<:@0-9.@:>@*\).*/\1/p'`
Expand Down Expand Up @@ -635,10 +635,10 @@
AC_C_RESTRICT

AC_HEADER_STDBOOL
AC_HEADER_STDC

Check warning on line 638 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-js

The macro `AC_HEADER_STDC' is obsolete.

Check warning on line 638 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-java-kotlin

The macro `AC_HEADER_STDC' is obsolete.
AC_HEADER_TIME

Check warning on line 639 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-js

The macro `AC_HEADER_TIME' is obsolete.

Check warning on line 639 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-java-kotlin

The macro `AC_HEADER_TIME' is obsolete.
AC_HEADER_SYS_WAIT
AC_TYPE_SIGNAL

Check warning on line 641 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-js

The macro `AC_TYPE_SIGNAL' is obsolete.

Check warning on line 641 in configure.ac

View workflow job for this annotation

GitHub Actions / lib-java-kotlin

The macro `AC_TYPE_SIGNAL' is obsolete.
AC_CHECK_HEADERS([arpa/inet.h])
AC_CHECK_HEADERS([fcntl.h])
AC_CHECK_HEADERS([inttypes.h])
Expand Down
2 changes: 1 addition & 1 deletion doc/thrift-threat-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ Thrift is a polyglot library; "the environment" varies per binding. Common assum

### Rust runtime (`lib/rs/`)

- **Rust 1.65+ since 0.14.0** *(documented — `lib/rs/README.md` §Thrift 0.14.0 / THRIFT-5158)*.
- **Rust 1.85+ since 0.26.0** *(documented — `lib/rs/README.md` §Thrift 0.26.0 / THRIFT-6162)*.
- **Past CVE-class:** THRIFT-5812 (capacity overflow in Rust server).

### What Thrift does *not* do to its host
Expand Down
3 changes: 2 additions & 1 deletion lib/rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[package]
name = "thrift"
description = "Rust bindings for the Apache Thrift RPC system"
edition = "2021"
edition = "2024"
rust-version = "1.85"
version = "0.26.0"
license = "Apache-2.0"
authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
Expand Down
12 changes: 8 additions & 4 deletions lib/rs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,19 @@ Full [Rustdoc](https://docs.rs/thrift/)

## Compatibility

The Rust library and auto-generated code target Rust versions 1.65+. The
minimum was raised from Rust 1.28 by THRIFT-5158, when the library and generator
moved to Rust 2021-only output. Enabling the optional `rustls` feature requires
Rust 1.71+.
The Rust library uses the Rust 2024 edition and requires Rust 1.85+, the
`rust-version` declared in `Cargo.toml`. CI builds and tests with the Rust
release pinned in the repository's `rust-toolchain` file.

### Breaking Changes

Breaking changes are minimized. When they are made they will be outlined below with transition guidelines.

##### Thrift 0.26.0

* **[THRIFT-6162]** - The library moved to the Rust 2024 edition and requires Rust 1.85 or higher.
Previously the documented minimum was Rust 1.65 (1.71 with the `rustls` feature).

##### Thrift 0.15.0

* **[THRIFT-5360]** - No longer define OR generate `description()` methods for `Error` types.
Expand Down
55 changes: 33 additions & 22 deletions lib/rs/src/protocol/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ where
kind: ProtocolErrorKind::Unknown,
message: format!(
"cannot write identifier {:?} without sequence number",
&identifier
identifier
),
}));
}
Expand Down Expand Up @@ -820,9 +820,11 @@ mod tests {
fn must_write_field_begin() {
let (_, mut o_prot) = test_objects(true);

assert!(o_prot
.write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
.is_ok());
assert!(
o_prot
.write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
.is_ok()
);

let expected: [u8; 3] = [0x0B, 0x00, 0x16];
assert_eq_written_bytes!(o_prot, expected);
Expand Down Expand Up @@ -883,9 +885,11 @@ mod tests {
fn must_write_list_begin() {
let (_, mut o_prot) = test_objects(true);

assert!(o_prot
.write_list_begin(&TListIdentifier::new(TType::Bool, 5))
.is_ok());
assert!(
o_prot
.write_list_begin(&TListIdentifier::new(TType::Bool, 5))
.is_ok()
);

let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
assert_eq_written_bytes!(o_prot, expected);
Expand Down Expand Up @@ -926,9 +930,11 @@ mod tests {
fn must_write_set_begin() {
let (_, mut o_prot) = test_objects(true);

assert!(o_prot
.write_set_begin(&TSetIdentifier::new(TType::I16, 7))
.is_ok());
assert!(
o_prot
.write_set_begin(&TSetIdentifier::new(TType::I16, 7))
.is_ok()
);

let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
assert_eq_written_bytes!(o_prot, expected);
Expand Down Expand Up @@ -968,9 +974,11 @@ mod tests {
fn must_write_map_begin() {
let (_, mut o_prot) = test_objects(true);

assert!(o_prot
.write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
.is_ok());
assert!(
o_prot
.write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
.is_ok()
);

let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20];
assert_eq_written_bytes!(o_prot, expected);
Expand Down Expand Up @@ -1250,9 +1258,10 @@ mod tests {
match result {
Err(crate::Error::Protocol(e)) => {
assert_eq!(e.kind, ProtocolErrorKind::SizeLimit);
assert!(e
.message
.contains("Container size 200 exceeds maximum allowed size of 100"));
assert!(
e.message
.contains("Container size 200 exceeds maximum allowed size of 100")
);
}
_ => panic!("Expected protocol error with SizeLimit"),
}
Expand Down Expand Up @@ -1304,9 +1313,10 @@ mod tests {
match result {
Err(crate::Error::Protocol(e)) => {
assert_eq!(e.kind, ProtocolErrorKind::SizeLimit);
assert!(e
.message
.contains("Byte array size 2000 exceeds maximum allowed size of 1000"));
assert!(
e.message
.contains("Byte array size 2000 exceeds maximum allowed size of 1000")
);
}
_ => panic!("Expected protocol error with SizeLimit"),
}
Expand All @@ -1331,9 +1341,10 @@ mod tests {
match result {
Err(crate::Error::Protocol(e)) => {
assert_eq!(e.kind, ProtocolErrorKind::SizeLimit);
assert!(e
.message
.contains("Message name size 2000 exceeds maximum allowed size of 1000"));
assert!(
e.message
.contains("Message name size 2000 exceeds maximum allowed size of 1000")
);
}
_ => panic!("Expected protocol error with SizeLimit"),
}
Expand Down
7 changes: 4 additions & 3 deletions lib/rs/src/protocol/compact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3176,9 +3176,10 @@ mod tests {
match result {
Err(crate::Error::Protocol(e)) => {
assert_eq!(e.kind, ProtocolErrorKind::SizeLimit);
assert!(e
.message
.contains("1600 bytes, exceeding message size limit of 1000"));
assert!(
e.message
.contains("1600 bytes, exceeding message size limit of 1000")
);
}
_ => panic!("Expected protocol error with SizeLimit"),
}
Expand Down
4 changes: 2 additions & 2 deletions lib/rs/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ pub trait TInputProtocol {
}
u => Err(crate::Error::Protocol(ProtocolError {
kind: ProtocolErrorKind::Unknown,
message: format!("cannot skip field type {:?}", &u),
message: format!("cannot skip field type {:?}", u),
})),
}
}
Expand Down Expand Up @@ -622,7 +622,7 @@ where
pub trait TOutputProtocolFactory {
/// Create a `TOutputProtocol` that writes bytes to `transport`.
fn create(&self, transport: Box<dyn TWriteTransport + Send>)
-> Box<dyn TOutputProtocol + Send>;
-> Box<dyn TOutputProtocol + Send>;
}

impl<T> TOutputProtocolFactory for Box<T>
Expand Down
2 changes: 1 addition & 1 deletion lib/rs/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub trait TProcessor {
///
/// Returns `()` if the handler was executed; `Err` otherwise.
fn process(&self, i: &mut dyn TInputProtocol, o: &mut dyn TOutputProtocol)
-> crate::Result<()>;
-> crate::Result<()>;
}

/// Convenience function used in generated `TProcessor` implementations to
Expand Down
8 changes: 4 additions & 4 deletions lib/rs/src/server/multiplexed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::sync::{Arc, Mutex};

use crate::protocol::{TInputProtocol, TMessageIdentifier, TOutputProtocol, TStoredInputProtocol};

use super::{handle_process_result, TProcessor};
use super::{TProcessor, handle_process_result};

const MISSING_SEPARATOR_AND_NO_DEFAULT: &str =
"missing service separator and no default processor set";
Expand Down Expand Up @@ -109,7 +109,7 @@ impl TMultiplexedProcessor {
o_prot: &mut dyn TOutputProtocol,
) -> crate::Result<()> {
let (svc_name, svc_call) = split_ident_name(&msg_ident.name);
debug!("routing svc_name {:?} svc_call {}", &svc_name, &svc_call);
debug!("routing svc_name {:?} svc_call {}", svc_name, svc_call);

let processor: Option<Arc<ThreadSafeProcessor>> = {
let stored = self.stored.lock().unwrap();
Expand Down Expand Up @@ -143,7 +143,7 @@ impl TProcessor for TMultiplexedProcessor {
) -> crate::Result<()> {
let msg_ident = i_prot.read_message_begin()?;

debug!("process incoming msg id:{:?}", &msg_ident);
debug!("process incoming msg id:{:?}", msg_ident);
let res = self.process_message(&msg_ident, i_prot, o_prot);

handle_process_result(&msg_ident, res, o_prot)
Expand Down Expand Up @@ -183,8 +183,8 @@ fn missing_processor_message(svc_name: Option<&str>) -> String {
#[cfg(test)]
mod tests {
use std::convert::Into;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};

use crate::protocol::{
TBinaryInputProtocol, TBinaryOutputProtocol, TMessageIdentifier, TMessageType,
Expand Down
2 changes: 1 addition & 1 deletion lib/rs/src/transport/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::time::Duration;
use std::os::unix::net::UnixStream;

use super::{ReadHalf, TIoChannel, WriteHalf};
use crate::{new_transport_error, TransportErrorKind};
use crate::{TransportErrorKind, new_transport_error};

/// Bidirectional TCP/IP channel.
///
Expand Down
2 changes: 1 addition & 1 deletion lib/rs/src/transport/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustls::{
};

use super::{ReadHalf, TIoChannel, TSharedChannel, WriteHalf};
use crate::{new_transport_error, TransportErrorKind};
use crate::{TransportErrorKind, new_transport_error};

/// A blocking rustls client channel.
///
Expand Down
3 changes: 2 additions & 1 deletion lib/rs/test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[package]
name = "kitchen-sink"
version = "0.1.0"
edition = "2021"
edition = "2024"
rust-version = "1.85"
license = "Apache-2.0"
authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
publish = false
Expand Down
3 changes: 2 additions & 1 deletion lib/rs/test/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
name = "thrift-fuzz"
version = "0.0.0"
publish = false
edition = "2021"
edition = "2024"
rust-version = "1.85"

[package.metadata]
cargo-fuzz = true
Expand Down
2 changes: 1 addition & 1 deletion lib/rs/test/fuzz/fuzz_targets/parse_binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

#![no_main]

use thrift::TConfiguration;
use thrift::protocol::TBinaryInputProtocol;
use thrift::protocol::TSerializable;
use thrift::transport::TBufferChannel;
use thrift::TConfiguration;
use thrift_fuzz::fuzz_test::FuzzTest;

fn run(data: &[u8]) -> thrift::Result<FuzzTest> {
Expand Down
Loading
Loading