File 1449.patch of Package paru
From 8e317fa211d3fa81eaaa939fe7eb9c916f6bc527 Mon Sep 17 00:00:00 2001
From: Edwin Peer <espeer@gmail.com>
Date: Mon, 24 Nov 2025 21:04:54 -0800
Subject: [PATCH] Don't rely on transparent decompression in list_aur
The current AUR package list code relies on the reqwest client library
to transparently decompress the packages.gz file. This only works if
the server provides the 'Content-Encoding: gzip" HTTP header, which
appears to have changed recently.
This patch explicitly decompresses the package list if no encoding
information is provided by the server.
Fixes: https://github.com/Morganamilo/paru/issues/1447
v2: blindly decompress with fall back on error, since reqwest strips
the content encoding header when it transparently decompresses.
v3: also fix same issue in completion.rs and search.rs
Signed-off-by: Edwin Peer <espeer@gmail.com>
---
Cargo.lock | 1 +
Cargo.toml | 1 +
src/completion.rs | 8 +++++++-
src/search.rs | 11 +++++++++--
src/sync.rs | 8 +++++++-
5 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index beba6693..37ab1515 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1509,6 +1509,7 @@ dependencies = [
"cini",
"dirs",
"env_logger",
+ "flate2",
"futures",
"globset",
"htmlescape",
diff --git a/Cargo.toml b/Cargo.toml
index 26063f75..39c67c14 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -57,6 +57,7 @@ regex = "1.11.1"
signal-hook = "0.3.18"
bitflags = "2.9.1"
toml = { version = "0.8.23", features = ["preserve_order"] }
+flate2 = "1.1"
[profile.release]
codegen-units = 1
diff --git a/src/completion.rs b/src/completion.rs
index 1745b1a7..f4eb7a07 100644
--- a/src/completion.rs
+++ b/src/completion.rs
@@ -2,11 +2,12 @@ use crate::config::Config;
use crate::print_error;
use std::fs::{create_dir_all, metadata, OpenOptions};
-use std::io::{stdout, BufRead, BufReader, Write};
+use std::io::{stdout, BufRead, BufReader, Read, Write};
use std::path::Path;
use std::time::{Duration, SystemTime};
use anyhow::{ensure, Context, Result};
+use flate2::read::GzDecoder;
use reqwest::get;
use tr::tr;
use url::Url;
@@ -20,6 +21,11 @@ async fn save_aur_list(aur_url: &Url, cache_dir: &Path) -> Result<()> {
ensure!(success, "get {}: {}", url, resp.status());
let data = resp.bytes().await?;
+ let mut extracted = Vec::new();
+ let data = match GzDecoder::new(&data[..]).read_to_end(&mut extracted) {
+ Ok(_) => extracted.into(),
+ Err(_) => data,
+ };
create_dir_all(cache_dir)?;
let path = cache_dir.join("packages.aur");
diff --git a/src/search.rs b/src/search.rs
index 5e88f515..d31ae913 100644
--- a/src/search.rs
+++ b/src/search.rs
@@ -1,3 +1,4 @@
+use std::io::Read;
use std::path::Path;
use crate::config::SortBy;
@@ -8,6 +9,7 @@ use crate::{info, printtr};
use ansiterm::Style;
use anyhow::{ensure, Context, Result};
+use flate2::read::GzDecoder;
use indicatif::HumanBytes;
use raur::{Raur, SearchBy};
use regex::RegexSet;
@@ -172,11 +174,16 @@ async fn search_aur_regex(config: &Config, targets: &[String]) -> Result<Vec<rau
let success = resp.status().is_success();
ensure!(success, "get {}: {}", url, resp.status());
- let data = resp.text().await?;
+ let data = resp.bytes().await?;
+ let mut extracted = Vec::new();
+ let data = match GzDecoder::new(&data[..]).read_to_end(&mut extracted) {
+ Ok(_) => extracted.into(),
+ Err(_) => data,
+ };
let regex = RegexSet::new(targets)?;
- let pkgs = data
+ let pkgs = str::from_utf8(&data)?
.lines()
.skip(1)
.filter(|pkg| regex.is_match(pkg))
diff --git a/src/sync.rs b/src/sync.rs
index ca5ee41d..1740e970 100644
--- a/src/sync.rs
+++ b/src/sync.rs
@@ -2,9 +2,10 @@ use crate::config::Config;
use crate::pkgbuild::PkgbuildRepos;
use crate::{exec, print_error};
-use std::io::Write;
+use std::io::{Read, Write};
use anyhow::{anyhow, ensure, Context, Result};
+use flate2::read::GzDecoder;
use raur::Raur;
use tr::tr;
@@ -105,6 +106,11 @@ pub async fn list_aur(config: &Config) -> Result<()> {
ensure!(success, "get {}: {}", url, resp.status());
let data = resp.bytes().await?;
+ let mut extracted = Vec::new();
+ let data = match GzDecoder::new(&data[..]).read_to_end(&mut extracted) {
+ Ok(_) => extracted.into(),
+ Err(_) => data,
+ };
let stdout = std::io::stdout();
let mut stdout = stdout.lock();