From 684efa2e0eadcf5b5d7d216ab8f5f5b1c68a35a6 Mon Sep 17 00:00:00 2001 From: Yip Coekjan <69834864+Coekjan@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:37:33 +0800 Subject: [PATCH] Raise error when failing to load & parse the specified certificate (#4554) --- crates/typst-cli/src/download.rs | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/crates/typst-cli/src/download.rs b/crates/typst-cli/src/download.rs index 38b16008..63a2e416 100644 --- a/crates/typst-cli/src/download.rs +++ b/crates/typst-cli/src/download.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use native_tls::{Certificate, TlsConnector}; -use once_cell::sync::Lazy; +use once_cell::sync::OnceCell; use ureq::Response; use crate::terminal; @@ -16,13 +16,22 @@ use crate::terminal; /// Keep track of this many download speed samples. const SPEED_SAMPLES: usize = 5; -/// Lazily loads a custom CA certificate if present, but if there's an error -/// loading certificate, it just uses the default configuration. -static CERT: Lazy> = Lazy::new(|| { - let path = crate::ARGS.cert.as_ref()?; - let pem = std::fs::read(path).ok()?; - Certificate::from_pem(&pem).ok() -}); +/// Load a certificate from the file system if the `--cert` argument or +/// `TYPST_CERT` environment variable is present. The certificate is cached for +/// efficiency. +/// +/// - Returns `None` if `--cert` and `TYPST_CERT` are not set. +/// - Returns `Some(Ok(cert))` if the certificate was loaded successfully. +/// - Returns `Some(Err(err))` if an error occurred while loading the certificate. +fn cert() -> Option> { + static CERT: OnceCell = OnceCell::new(); + crate::ARGS.cert.as_ref().map(|path| { + CERT.get_or_try_init(|| { + let pem = std::fs::read(path)?; + Certificate::from_pem(&pem).map_err(io::Error::other) + }) + }) +} /// Download binary data and display its progress. #[allow(clippy::result_large_err)] @@ -49,8 +58,8 @@ pub fn download(url: &str) -> Result { } // Apply a custom CA certificate if present. - if let Some(cert) = &*CERT { - tls.add_root_certificate(cert.clone()); + if let Some(cert) = cert() { + tls.add_root_certificate(cert?.clone()); } // Configure native TLS.