From 3a9b9b34084b993e457498b1b5ddf5f281d23a84 Mon Sep 17 00:00:00 2001 From: damiondoesthings <80198756+damiondoesthings@users.noreply.github.com> Date: Mon, 12 Dec 2022 07:00:58 +0100 Subject: [PATCH] fix truncating signature on SAS (#1007) # Description This fixes the truncation of Azure SAS signatures ending in "=", i.e. when using non-url-encoded SAS tokens. # Related Issue(s) closes #1003 Co-authored-by: Damion Werner --- python/tests/test_fs.py | 18 ++++++++++++++++++ rust/src/builder/azure.rs | 15 ++++----------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/python/tests/test_fs.py b/python/tests/test_fs.py index 4113b9a2a6..62cdcb8b01 100644 --- a/python/tests/test_fs.py +++ b/python/tests/test_fs.py @@ -1,3 +1,5 @@ +import urllib + import pyarrow as pa import pyarrow.parquet as pq import pytest @@ -204,3 +206,19 @@ def test_roundtrip_azure_sas(azurite_sas_creds, sample_data: pa.Table): table = dt.to_pyarrow_table() assert table == sample_data assert dt.version() == 0 + + +@pytest.mark.azure +@pytest.mark.integration +@pytest.mark.timeout(timeout=5, method="thread") +def test_roundtrip_azure_decoded_sas(azurite_sas_creds, sample_data: pa.Table): + table_path = "az://deltars/roundtrip4" + azurite_sas_creds["SAS_TOKEN"] = urllib.parse.unquote( + azurite_sas_creds["SAS_TOKEN"] + ) + + write_deltalake(table_path, sample_data, storage_options=azurite_sas_creds) + dt = DeltaTable(table_path, storage_options=azurite_sas_creds) + table = dt.to_pyarrow_table() + assert table == sample_data + assert dt.version() == 0 diff --git a/rust/src/builder/azure.rs b/rust/src/builder/azure.rs index 07753fbe6b..448f8379ad 100644 --- a/rust/src/builder/azure.rs +++ b/rust/src/builder/azure.rs @@ -226,17 +226,10 @@ fn split_sas(sas: &str) -> Result, BuilderError> { .filter(|s| !s.chars().all(char::is_whitespace)); let mut pairs = Vec::new(); for kv_pair_str in kv_str_pairs { - let mut kv = kv_pair_str.trim().split('='); - let k = match kv.next().filter(|k| !k.chars().all(char::is_whitespace)) { - None => { - return Err(BuilderError::MissingCredential); - } - Some(k) => k, - }; - let v = match kv.next().filter(|k| !k.chars().all(char::is_whitespace)) { - None => return Err(BuilderError::MissingCredential), - Some(v) => v, - }; + let (k, v) = kv_pair_str + .trim() + .split_once('=') + .ok_or(BuilderError::MissingCredential)?; pairs.push((k.into(), v.into())) } Ok(pairs)