Skip to content

Commit e1cf63c

Browse files
committed
fix: restore startup config integrity
1 parent 98b5ec7 commit e1cf63c

4 files changed

Lines changed: 68 additions & 20 deletions

File tree

.github/workflows/tauri-build-win-official.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ jobs:
140140
Set-ConfigValue '^(updater_temp_dir\s*=\s*)".*"$' "${{ env.APP_UPDATER_TEMP_DIR }}"
141141
Set-ConfigValue '^(downlaod_url\s*=\s*)".*"$' "${{ env.APP_WEBVIEW_DOWNLOAD_URL }}"
142142
143-
Set-Content -Path $configPath -Value $content -NoNewline
143+
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
144+
$resolvedConfigPath = (Resolve-Path $configPath).Path
145+
[System.IO.File]::WriteAllText($resolvedConfigPath, $content, $utf8NoBom)
144146
145147
# 在 CI 构建期间使用 fixed 版本的 Tauri 配置
146148
# 先将 src-tauri/tauri.conf.fixed.json 覆盖为 src-tauri/tauri.conf.json,
@@ -173,15 +175,15 @@ jobs:
173175
run: node deploy/generate-latest-json.mjs
174176

175177
- name: Publish GitHub release assets
176-
if: github.event_name == 'push'
178+
if: startsWith(github.ref, 'refs/tags/')
177179
env:
178180
GH_TOKEN: ${{ secrets.GT_TOKEN || github.token }}
179181
GH_REPO: ${{ github.repository }}
180182
run: node deploy/publish-github-release.mjs
181183

182184
- name: Upload installer to R2 storage
183185
# tag push 时上传到 R2
184-
if: github.event_name == 'push'
186+
if: startsWith(github.ref, 'refs/tags/')
185187
shell: powershell
186188
run: |
187189
$ErrorActionPreference = "Stop"
@@ -215,7 +217,7 @@ jobs:
215217
216218
- name: Upload latest.json to R2 root
217219
# tag push 时上传到 R2
218-
if: github.event_name == 'push'
220+
if: startsWith(github.ref, 'refs/tags/')
219221
shell: powershell
220222
run: |
221223
$ErrorActionPreference = "Stop"
@@ -244,7 +246,7 @@ jobs:
244246
path: latest.json
245247

246248
- name: Publish version metadata
247-
if: github.event_name == 'push'
249+
if: startsWith(github.ref, 'refs/tags/')
248250
env:
249251
VERSION_API_URL: ${{ secrets.VERSION_API_URL }}
250252
VERSION_API_KEY: ${{ secrets.VERSION_API_KEY }}

.github/workflows/tauri-release-win.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ jobs:
8686
Set-ConfigValue '^(updater_temp_dir\s*=\s*)".*"$' "${{ env.APP_UPDATER_TEMP_DIR }}"
8787
Set-ConfigValue '^(downlaod_url\s*=\s*)".*"$' "${{ env.APP_WEBVIEW_DOWNLOAD_URL }}"
8888
89-
Set-Content -Path $configPath -Value $content -NoNewline
89+
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
90+
$resolvedConfigPath = (Resolve-Path $configPath).Path
91+
[System.IO.File]::WriteAllText($resolvedConfigPath, $content, $utf8NoBom)
9092
9193
- name: Use fixed Tauri config
9294
shell: powershell

src-tauri/build.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,15 @@ mod config_encrypt {
385385
);
386386
});
387387

388+
std::str::from_utf8(&config_bytes).unwrap_or_else(|e| {
389+
panic!(
390+
"[BUILD ERROR] Config file '{}' is not valid UTF-8: {}\n\
391+
Please ensure workflow/local scripts write this file with UTF-8 encoding.",
392+
config_path.display(),
393+
e
394+
);
395+
});
396+
388397
let encrypted = crypto::encrypt(&config_bytes).expect("Failed to encrypt config");
389398

390399
let out_path = Path::new(&out_dir).join("config_encrypted.bin");

src-tauri/src/core/config/encryption/crypto.rs

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,10 @@ fn pre_transform(data: &[u8], key: &[u8; 16]) -> Vec<u8> {
7878
result.push(byte ^ key[i % 16]);
7979
}
8080

81-
// 字节重排(简单的置换)
82-
let mut permuted = vec![0u8; result.len()];
83-
for (i, &byte) in result.iter().enumerate() {
84-
let new_pos = (i.wrapping_mul(7).wrapping_add(13)) % result.len();
85-
permuted[new_pos] = byte;
86-
}
87-
88-
permuted
81+
result.reverse();
82+
let shift = transform_shift(result.len(), key);
83+
result.rotate_left(shift);
84+
result
8985
}
9086

9187
/// 数据预变换的逆操作
@@ -94,12 +90,10 @@ fn pre_transform_reverse(data: &[u8], key: &[u8; 16]) -> Vec<u8> {
9490
return Vec::new();
9591
}
9692

97-
// 逆置换:对于每个原始位置 i,找到它在加密后的位置
98-
let mut unpermuted = vec![0u8; data.len()];
99-
for i in 0..data.len() {
100-
let encrypted_pos = (i.wrapping_mul(7).wrapping_add(13)) % data.len();
101-
unpermuted[i] = data[encrypted_pos];
102-
}
93+
let mut unpermuted = data.to_vec();
94+
let shift = transform_shift(unpermuted.len(), key);
95+
unpermuted.rotate_right(shift);
96+
unpermuted.reverse();
10397

10498
// 逆 XOR
10599
let mut result = Vec::with_capacity(unpermuted.len());
@@ -243,3 +237,44 @@ fn post_transform(data: &[u8], key: &[u8; 16]) -> Vec<u8> {
243237
fn post_transform_reverse(data: &[u8], key: &[u8; 16]) -> Vec<u8> {
244238
data.iter().enumerate().map(|(i, &b)| b.wrapping_sub(key[i % 16])).collect()
245239
}
240+
241+
fn transform_shift(len: usize, key: &[u8; 16]) -> usize {
242+
if len <= 1 {
243+
return 0;
244+
}
245+
246+
let seed = key
247+
.iter()
248+
.take(4)
249+
.fold(0usize, |acc, byte| (acc << 8) | (*byte as usize));
250+
(seed.wrapping_add(len).wrapping_add(13)) % len
251+
}
252+
253+
#[cfg(test)]
254+
mod tests {
255+
use super::{decrypt, encrypt};
256+
257+
#[test]
258+
fn roundtrip_preserves_all_lengths_up_to_1024() {
259+
for len in 0..=1024usize {
260+
let input = (0..len)
261+
.map(|index| ((index * 31 + 17) % 256) as u8)
262+
.collect::<Vec<_>>();
263+
let encrypted = encrypt(&input).expect("encrypt should succeed");
264+
let decrypted = decrypt(&encrypted).expect("decrypt should succeed");
265+
assert_eq!(decrypted, input, "roundtrip mismatch for len={len}");
266+
}
267+
}
268+
269+
#[test]
270+
fn roundtrip_preserves_lengths_that_are_multiples_of_seven() {
271+
for len in [7usize, 14, 497, 504, 4095, 4096, 4097] {
272+
let input = (0..len)
273+
.map(|index| ((index * 13 + 29) % 256) as u8)
274+
.collect::<Vec<_>>();
275+
let encrypted = encrypt(&input).expect("encrypt should succeed");
276+
let decrypted = decrypt(&encrypted).expect("decrypt should succeed");
277+
assert_eq!(decrypted, input, "roundtrip mismatch for len={len}");
278+
}
279+
}
280+
}

0 commit comments

Comments
 (0)