fix(bundler/nsis): write installer templates UTF16LE encoded, closes #7036 (#7040)

* fix(bundler/nsis): write installer templates UTF16LE encoded, closes #7036

* cleanup

* lint

* return err instead of panic

* Update .changes/nsis-encoding.md [skip ci]

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
Amr Bashir
2023-05-23 19:00:21 +03:00
committed by GitHub
parent 8b9f6cf868
commit 17da87d3cd
5 changed files with 88 additions and 130 deletions

View File

@@ -0,0 +1,5 @@
---
'tauri-bundler': 'patch:bug'
---
Fix NSIS bundler failing to build when `productName` contained chinsese characters.

View File

@@ -31,7 +31,6 @@ handlebars = "4.3"
tempfile = "3.5.0"
log = { version = "0.4.17", features = [ "kv_unstable" ] }
dirs-next = "2.0"
encoding_rs = "0.8"
os_pipe = "1"
attohttpc = { version = "0.25", default-features = false }
hex = "0.4"

View File

@@ -258,16 +258,14 @@ fn build_nsis_app_installer(
}),
);
let languages_data = languages
.iter()
.filter_map(|lang| {
if let Some(data) = get_lang_data(lang, custom_language_files.as_ref()) {
Some(data)
let mut languages_data = Vec::new();
for lang in &languages {
if let Some(data) = get_lang_data(lang, custom_language_files.as_ref())? {
languages_data.push(data);
} else {
log::warn!("Custom tauri messages for {lang} are not translated.\nIf it is a valid language listed on <https://github.com/kichik/nsis/tree/9465c08046f00ccb6eda985abbdbf52c275c6c4d/Contrib/Language%20files>, please open a Tauri feature request\n or you can provide a custom language file for it in `tauri.conf.json > tauri > bundle > windows > nsis > custom_language_files`");
None
}
}).collect::<Vec<_>>();
}
data.insert("languages", to_json(languages.clone()));
data.insert(
@@ -417,19 +415,14 @@ fn build_nsis_app_installer(
.expect("Failed to setup handlebar template");
}
let installer_nsi_path = output_path.join("installer.nsi");
write(
write_ut16_le_with_bom(
&installer_nsi_path,
encoding_rs::UTF_8
.encode(handlebars.render("installer.nsi", &data)?.as_str())
.0,
handlebars.render("installer.nsi", &data)?.as_str(),
)?;
for (lang, data) in languages_data.iter() {
if let Some((content, encoding)) = data {
write(
output_path.join(lang).with_extension("nsh"),
encoding.encode(content).0,
)?;
if let Some(content) = data {
write_ut16_le_with_bom(output_path.join(lang).with_extension("nsh"), content)?;
}
}
@@ -553,113 +546,44 @@ fn generate_binaries_data(settings: &Settings) -> crate::Result<BinariesMap> {
fn get_lang_data(
lang: &str,
custom_lang_files: Option<&HashMap<String, PathBuf>>,
) -> Option<(
String,
Option<(&'static str, &'static encoding_rs::Encoding)>,
)> {
use encoding_rs::*;
) -> crate::Result<Option<(PathBuf, Option<&'static str>)>> {
if let Some(path) = custom_lang_files.and_then(|h| h.get(lang)) {
return Some((
dunce::canonicalize(path)
.unwrap()
.to_string_lossy()
.to_string(),
None,
));
return Ok(Some((dunce::canonicalize(path)?, None)));
}
let lang_file = format!("{lang}.nsh");
match lang.to_lowercase().as_str() {
"arabic" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/Arabic.nsh"),
UTF_16LE,
)),
let lang_path = PathBuf::from(format!("{lang}.nsh"));
let lang_content = match lang.to_lowercase().as_str() {
"arabic" => Some(include_str!("./templates/nsis-languages/Arabic.nsh")),
"dutch" => Some(include_str!("./templates/nsis-languages/Dutch.nsh")),
"english" => Some(include_str!("./templates/nsis-languages/English.nsh")),
"japanese" => Some(include_str!("./templates/nsis-languages/Japanese.nsh")),
"korean" => Some(include_str!("./templates/nsis-languages/Korean.nsh")),
"portuguesebr" => Some(include_str!("./templates/nsis-languages/PortugueseBR.nsh")),
"tradchinese" => Some(include_str!("./templates/nsis-languages/TradChinese.nsh")),
"simpchinese" => Some(include_str!("./templates/nsis-languages/SimpChinese.nsh")),
"french" => Some(include_str!("./templates/nsis-languages/French.nsh")),
"spanish" => Some(include_str!("./templates/nsis-languages/Spanish.nsh")),
"spanishinternational" => Some(include_str!(
"./templates/nsis-languages/SpanishInternational.nsh"
)),
"dutch" => Some((
lang_file,
Some((include_str!("./templates/nsis-languages/Dutch.nsh"), UTF_8)),
)),
"english" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/English.nsh"),
UTF_8,
)),
)),
"japanese" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/Japanese.nsh"),
UTF_8,
)),
)),
"korean" => Some((
lang_file,
Some((include_str!("./templates/nsis-languages/Korean.nsh"), UTF_8)),
)),
"portuguesebr" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/PortugueseBR.nsh"),
UTF_8,
)),
)),
"tradchinese" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/TradChinese.nsh"),
UTF_8,
)),
)),
"simpchinese" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/SimpChinese.nsh"),
UTF_8,
)),
)),
"french" => Some((
lang_file,
Some((include_str!("./templates/nsis-languages/French.nsh"), UTF_8)),
)),
"spanish" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/Spanish.nsh"),
UTF_8,
)),
)),
"spanishinternational" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/SpanishInternational.nsh"),
UTF_8,
)),
)),
"persian" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/Persian.nsh"),
UTF_16LE,
)),
)),
"turkish" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/Turkish.nsh"),
UTF_8,
)),
)),
"swedish" => Some((
lang_file,
Some((
include_str!("./templates/nsis-languages/Swedish.nsh"),
UTF_8,
)),
)),
_ => None,
}
"persian" => Some(include_str!("./templates/nsis-languages/Persian.nsh")),
"turkish" => Some(include_str!("./templates/nsis-languages/Turkish.nsh")),
"swedish" => Some(include_str!("./templates/nsis-languages/Swedish.nsh")),
_ => return Ok(None),
};
Ok(Some((lang_path, lang_content)))
}
fn write_ut16_le_with_bom<P: AsRef<Path>>(path: P, content: &str) -> crate::Result<()> {
use std::fs::File;
use std::io::{BufWriter, Write};
let file = File::create(path)?;
let mut output = BufWriter::new(file);
output.write_all(&[0xFF, 0xFE])?; // the BOM part
for utf16 in content.encode_utf16() {
output.write_all(&utf16.to_le_bytes())?;
}
Ok(())
}

View File

@@ -24,4 +24,4 @@ LangString webview2DownloadSuccess ${LANG_PERSIAN} "WebView2 بوت استرپر
LangString webview2Downloading ${LANG_PERSIAN} "دانلود بوت استرپر WebView2..."
LangString webview2InstallError ${LANG_PERSIAN} "ارور: نصب WebView2 با کد $1 شکست خورد"
LangString webview2InstallSuccess ${LANG_PERSIAN} "WebView2 با موفقیت نصب شد"
LangString deleteAppData ${LANG_PERSIAN} "حذف دیتا های اپلیکیشن"
LangString deleteAppData ${LANG_PERSIAN} "حذف دیتا های اپلیکیشن"

44
tooling/cli/Cargo.lock generated
View File

@@ -163,17 +163,17 @@ dependencies = [
[[package]]
name = "attohttpc"
version = "0.24.1"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2"
checksum = "7e57d6e7a84f33ff3316e97af3180fe7f86597a6a60161c0be70c0e45f382620"
dependencies = [
"http",
"log",
"native-tls",
"rustls",
"rustls 0.21.1",
"url",
"webpki",
"webpki-roots",
"webpki-roots 0.23.0",
]
[[package]]
@@ -2764,6 +2764,28 @@ dependencies = [
"webpki",
]
[[package]]
name = "rustls"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e"
dependencies = [
"log",
"ring",
"rustls-webpki",
"sct",
]
[[package]]
name = "rustls-webpki"
version = "0.100.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "ryu"
version = "1.0.13"
@@ -3253,7 +3275,6 @@ dependencies = [
"bitness",
"dirs-next",
"dunce",
"encoding_rs",
"glob",
"handlebars",
"heck",
@@ -3762,10 +3783,10 @@ dependencies = [
"flate2",
"log",
"once_cell",
"rustls",
"rustls 0.20.8",
"url",
"webpki",
"webpki-roots",
"webpki-roots 0.22.6",
]
[[package]]
@@ -3952,6 +3973,15 @@ dependencies = [
"webpki",
]
[[package]]
name = "webpki-roots"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa54963694b65584e170cf5dc46aeb4dcaa5584e652ff5f3952e56d66aff0125"
dependencies = [
"rustls-webpki",
]
[[package]]
name = "weezl"
version = "0.1.7"