From c9945bca5db2d2d6009a6a883aec8bf7391ad835 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 19:08:54 +0000 Subject: [PATCH] chore(deps): bump sha2 from 0.10.9 to 0.11.0 (#8963) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jack Amadeo --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- crates/goose-cli/src/commands/update.rs | 2 +- crates/goose/src/goose_apps/cache.rs | 5 +++-- crates/goose/src/providers/inventory/mod.rs | 3 ++- crates/goose/src/providers/oauth.rs | 3 ++- crates/goose/src/providers/testprovider.rs | 3 ++- crates/goose/src/utils.rs | 24 +++++++++++++++++++++ 8 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5afe245..c8f2a818 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4532,7 +4532,7 @@ dependencies = [ "serde_urlencoded", "serde_yaml", "serial_test", - "sha2 0.10.9", + "sha2 0.11.0", "shell-words", "shellexpand", "smithy-transport-reqwest", @@ -4621,7 +4621,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "sha2 0.10.9", + "sha2 0.11.0", "shlex", "sigstore-verify", "strum 0.27.2", diff --git a/Cargo.toml b/Cargo.toml index 27e84329..2774b0a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ winapi = { version = "0.3.9", default-features = false, features = ["wincred", " wiremock = { version = "0.6", default-features = false } zip = { version = "8", default-features = false, features = ["deflate"] } serial_test = { version = "3", default-features = false } -sha2 = { version = "0.10.8", default-features = false, features = ["std"] } +sha2 = { version = "0.11", default-features = false } shell-words = { version = "1", default-features = false, features = ["std"] } test-case = { version = "3", default-features = false } url = { version = "2.5.4", default-features = false, features = ["std"] } diff --git a/crates/goose-cli/src/commands/update.rs b/crates/goose-cli/src/commands/update.rs index 73a69503..04272d20 100644 --- a/crates/goose-cli/src/commands/update.rs +++ b/crates/goose-cli/src/commands/update.rs @@ -64,7 +64,7 @@ fn binary_name() -> &'static str { fn sha256_hex(data: &[u8]) -> String { let mut hasher = Sha256::new(); hasher.update(data); - format!("{:x}", hasher.finalize()) + goose::utils::bytes_to_hex(hasher.finalize()) } #[derive(serde::Deserialize)] diff --git a/crates/goose/src/goose_apps/cache.rs b/crates/goose/src/goose_apps/cache.rs index c6364030..36582829 100644 --- a/crates/goose/src/goose_apps/cache.rs +++ b/crates/goose/src/goose_apps/cache.rs @@ -1,4 +1,5 @@ use crate::config::paths::Paths; +use crate::utils::bytes_to_hex; use sha2::{Digest, Sha256}; use std::fs; use std::path::PathBuf; @@ -36,8 +37,8 @@ impl McpAppCache { fn cache_key(extension_name: &str, resource_uri: &str) -> String { let input = format!("{}::{}", extension_name, resource_uri); - let hash = Sha256::digest(input.as_bytes()); - format!("{}_{:x}", extension_name, hash) + let hash = bytes_to_hex(Sha256::digest(input.as_bytes())); + format!("{}_{}", extension_name, hash) } pub fn list_apps(&self) -> Result, std::io::Error> { diff --git a/crates/goose/src/providers/inventory/mod.rs b/crates/goose/src/providers/inventory/mod.rs index dae24e7b..f363d696 100644 --- a/crates/goose/src/providers/inventory/mod.rs +++ b/crates/goose/src/providers/inventory/mod.rs @@ -4,6 +4,7 @@ use super::catalog::ProviderSetupCategory; use crate::config::declarative_providers::{DeclarativeProviderConfig, ProviderEngine}; use crate::config::Config; use crate::session::session_manager::SessionStorage; +use crate::utils::bytes_to_hex; use anyhow::{Context, Result}; use chrono::{DateTime, Duration, Utc}; use serde::{Deserialize, Serialize}; @@ -126,7 +127,7 @@ impl InventoryIdentityInput { Ok(InventoryIdentity { provider_id, provider_family, - inventory_key: format!("{digest:x}"), + inventory_key: bytes_to_hex(digest), }) } } diff --git a/crates/goose/src/providers/oauth.rs b/crates/goose/src/providers/oauth.rs index e27ba808..432dd014 100644 --- a/crates/goose/src/providers/oauth.rs +++ b/crates/goose/src/providers/oauth.rs @@ -1,4 +1,5 @@ use crate::config::paths::Paths; +use crate::utils::bytes_to_hex; use anyhow::Result; use axum::{extract::Query, response::Html, routing::get, Router}; use base64::Engine; @@ -56,7 +57,7 @@ impl TokenCache { hasher.update(host.as_bytes()); hasher.update(client_id.as_bytes()); hasher.update(scopes.join(",").as_bytes()); - let hash = format!("{:x}", hasher.finalize()); + let hash = bytes_to_hex(hasher.finalize()); fs::create_dir_all(get_base_path()).unwrap(); let cache_path = get_base_path().join(format!("{}.json", hash)); diff --git a/crates/goose/src/providers/testprovider.rs b/crates/goose/src/providers/testprovider.rs index 5f58c2f9..e06d1f27 100644 --- a/crates/goose/src/providers/testprovider.rs +++ b/crates/goose/src/providers/testprovider.rs @@ -13,6 +13,7 @@ use super::base::{MessageStream, Provider, ProviderDef, ProviderMetadata, Provid use super::errors::ProviderError; use crate::conversation::message::{Message, ToolResponse}; use crate::model::ModelConfig; +use crate::utils::bytes_to_hex; use futures::future::BoxFuture; use rmcp::model::{CallToolResult, Tool}; @@ -111,7 +112,7 @@ impl TestProvider { let serialized = serde_json::to_string(&stable_messages).unwrap_or_default(); let mut hasher = Sha256::new(); hasher.update(serialized.as_bytes()); - format!("{:x}", hasher.finalize()) + bytes_to_hex(hasher.finalize()) } fn load_records(file_path: &str) -> Result> { diff --git a/crates/goose/src/utils.rs b/crates/goose/src/utils.rs index b78d4a4a..dee7fc4e 100644 --- a/crates/goose/src/utils.rs +++ b/crates/goose/src/utils.rs @@ -1,6 +1,23 @@ use tokio_util::sync::CancellationToken; use unicode_normalization::UnicodeNormalization; +/// Encode bytes as a lowercase hexadecimal string. +/// +/// This avoids relying on digest output types implementing `LowerHex`, which +/// changed in sha2 0.11. +pub fn bytes_to_hex(bytes: impl AsRef<[u8]>) -> String { + const HEX: &[u8; 16] = b"0123456789abcdef"; + let bytes = bytes.as_ref(); + let mut output = String::with_capacity(bytes.len() * 2); + + for &byte in bytes { + output.push(HEX[(byte >> 4) as usize] as char); + output.push(HEX[(byte & 0x0f) as usize] as char); + } + + output +} + /// Check if a character is in the Unicode Tags Block range (U+E0000-U+E007F) /// These characters are invisible and can be used for steganographic attacks fn is_in_unicode_tag_range(c: char) -> bool { @@ -83,6 +100,13 @@ pub fn split_command_args(input: &str) -> anyhow::Result> { mod tests { use super::*; + #[test] + fn test_bytes_to_hex() { + assert_eq!(bytes_to_hex([]), ""); + assert_eq!(bytes_to_hex([0x00, 0x0f, 0x10, 0xab, 0xff]), "000f10abff"); + assert_eq!(bytes_to_hex(b"hello world"), "68656c6c6f20776f726c64"); + } + #[test] fn test_contains_unicode_tags() { // Test detection of Unicode Tags Block characters