Skip to content

Commit

Permalink
fix(bundler/nsis): write installer templates UTF16LE encoded, closes #…
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
amrbashir and lucasfernog authored May 23, 2023
1 parent 8b9f6cf commit 17da87d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 129 deletions.
5 changes: 5 additions & 0 deletions .changes/nsis-encoding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri-bundler': 'patch:bug'
---

Fix NSIS bundler failing to build when `productName` contained chinsese characters.
1 change: 0 additions & 1 deletion tooling/bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
164 changes: 44 additions & 120 deletions tooling/bundler/src/bundle/windows/nsis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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)?;
}
}

Expand Down Expand Up @@ -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,
)),
)),
"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)),
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"
)),
"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(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 37 additions & 7 deletions tooling/cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 17da87d

Please sign in to comment.