Skip to content

Commit a75d4bb

Browse files
committed
Refactor decode_base64() function for better error handling
1 parent f634968 commit a75d4bb

File tree

2 files changed

+45
-33
lines changed

2 files changed

+45
-33
lines changed

src/mihoro.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ use crate::cmd::ProxyCommands;
22
use crate::config::{apply_mihomo_override, parse_config, Config, EncodingMode};
33
use crate::proxy::{proxy_export_cmd, proxy_unset_cmd};
44
use crate::systemctl::Systemctl;
5-
use crate::utils::{create_parent_dir, decode_base64, delete_file, download_file, extract_gzip};
5+
use crate::utils::{
6+
create_parent_dir, try_decode_base64_file_inplace, delete_file, download_file, extract_gzip,
7+
};
68

79
use std::fs;
810
use std::os::unix::prelude::PermissionsExt;
@@ -86,7 +88,7 @@ impl Mihoro {
8688

8789
//Try to Decode base64 config if set
8890
if self.config.remote_config_encoding == EncodingMode::Base64 {
89-
decode_base64(&self.mihomo_target_config_path)?;
91+
try_decode_base64_file_inplace(&self.mihomo_target_config_path)?;
9092
}
9193

9294
apply_mihomo_override(&self.mihomo_target_config_path, &self.config.mihomo_config)?;

src/utils.rs

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
use anyhow::{anyhow, Context, Result};
2-
use base64::prelude::BASE64_STANDARD;
3-
use base64::Engine;
4-
use colored::Colorize;
5-
use flate2::read::GzDecoder;
6-
use futures_util::StreamExt;
7-
use indicatif::{ProgressBar, ProgressStyle};
8-
use reqwest::Client;
9-
use std::fs::OpenOptions;
10-
use std::io::{Read, Seek, SeekFrom};
111
use std::{
122
cmp::min,
133
fs::{self, File},
14-
io::{self, Write},
4+
io::{self, BufWriter, Read, Seek, SeekFrom, Write},
155
path::Path,
166
};
7+
8+
use anyhow::{Context, Result};
9+
use base64::{prelude::BASE64_STANDARD, Engine};
10+
use colored::Colorize;
11+
use flate2::read::GzDecoder;
12+
use futures_util::StreamExt;
13+
use indicatif::{ProgressBar, ProgressStyle};
14+
use reqwest::Client;
1715
use truncatable::Truncatable;
1816

1917
/// Creates the parent directory for a given path if it does not exist.
@@ -129,27 +127,39 @@ pub fn extract_gzip(gzip_path: &str, filename: &str, prefix: &str) -> Result<()>
129127
);
130128
Ok(())
131129
}
132-
//try to decode a base64 file in place, the file must exist,if the file is not base64 encoded ,it is ok
133-
pub fn decode_base64(filename: &str) -> Result<()> {
134-
// copy file to buffer
135-
let mut file = OpenOptions::new().read(true).write(true).open(filename)?;
136-
let mut base64_buf = Vec::<u8>::new();
130+
131+
/// Try and decode a base64 encoded file in place.
132+
///
133+
/// Decodes the base64 encoded content of a file in place and writes the decoded content back to the
134+
/// file. If the file does not contain base64 encoded content, maintains the file as is.
135+
///
136+
/// # Arguments
137+
///
138+
/// * `filename` - A string slice that holds the path to the file to decode.
139+
pub fn try_decode_base64_file_inplace(filename: &str) -> Result<()> {
140+
// Open the file for reading and writing
141+
let mut file = File::open(filename)?;
142+
let mut base64_buf = Vec::new();
143+
144+
// Read the file content into the buffer
137145
file.read_to_end(&mut base64_buf)?;
138-
//try decode
139-
let decoded = BASE64_STANDARD.decode(base64_buf.as_slice());
140-
// the file is not base64 encoded .It is ok .Do Nothing
141-
if let Err(_) = decoded {
142-
return Ok(());
143-
}
144-
//try to clear file
145-
if let Err(e) = file.set_len(0) {
146-
return Err(anyhow!("fail to clear file,why? {}", e));
147-
}
148-
if let Err(e) = file.seek(SeekFrom::Start(0)) {
149-
return Err(anyhow!("fail to clear file,why? {}", e));
146+
147+
// Try to decode the base64 content
148+
match BASE64_STANDARD.decode(&base64_buf) {
149+
Ok(decoded_bytes) => {
150+
// Truncate the file and seek to the beginning
151+
file.set_len(0)?;
152+
file.seek(SeekFrom::Start(0))?;
153+
154+
// Write the decoded bytes back to the file
155+
let mut writer = BufWriter::new(&file);
156+
writer.write_all(&decoded_bytes)?;
157+
}
158+
Err(_) => {
159+
// If decoding fails, do nothing and return Ok
160+
return Ok(());
161+
}
150162
}
151-
//write bytes to file
152-
let decoded_bytes = decoded.expect("this can't be happening");
153-
file.write_all(&decoded_bytes)?;
163+
154164
Ok(())
155165
}

0 commit comments

Comments
 (0)