mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
Sanitize picker file paths (spaces / non-ANSI) and shell prompts
Issue #665: the Windows ROM and save pickers returned the raw chosen path. io.open on Windows needs ANSI bytes, so a path with accented characters (Pokemon -> Pok\x82mon, or a folder like 'Pokemon Gen1') could never be opened -- the same bug #325 already fixed for mod zips by copying to a plain-ASCII temp name. Apply that fix to the ROM and .sav pickers: each copies its pick to an ASCII temp name (pokeport_rom_pick.gb / pokeport_sav_pick.sav) before answering, exactly like chooseZip does. Also sanitize the prompt strings interpolated into the picker shell commands: '%' would be eaten as a string.format directive, and quotes would break the AppleScript/zenity argument or the surrounding shell string. Fixes #665
This commit is contained in:
@@ -337,6 +337,15 @@ local function commandOutput(command)
|
||||
return result ~= "" and result or nil
|
||||
end
|
||||
|
||||
-- Sanitize a string before it is interpolated into a picker shell command:
|
||||
-- * "%" would be eaten as a string.format directive (#665);
|
||||
-- * '"' would break the AppleScript / zenity double-quoted argument and
|
||||
-- "'" the surrounding single-quoted shell string.
|
||||
local function shellSafe(s)
|
||||
s = tostring(s):gsub("%%", "%%%%")
|
||||
return s:gsub('"', '\\"'):gsub("'", "''")
|
||||
end
|
||||
|
||||
-- LOVE 11.5 on Android has no native file picker (love.window.showFileDialog
|
||||
-- is a LOVE 12 nightly-only addition) and never fires love.filedropped, so
|
||||
-- neither desktop path below works there. conf.lua points the Android save
|
||||
@@ -443,7 +452,7 @@ end
|
||||
|
||||
local function chooseRom(promptName)
|
||||
promptName = promptName or "Pokemon"
|
||||
local prompt = "Choose your " .. promptName .. " ROM"
|
||||
local prompt = shellSafe("Choose your " .. promptName .. " ROM")
|
||||
local platform = love.system.getOS()
|
||||
if platform == "OS X" then
|
||||
return commandOutput(
|
||||
@@ -455,10 +464,16 @@ local function chooseRom(promptName)
|
||||
"$d=New-Object System.Windows.Forms.OpenFileDialog;",
|
||||
"$d.Title='" .. prompt .. "';",
|
||||
"$d.Filter='Game Boy ROM (*.gb;*.gbc)|*.gb;*.gbc|All files (*.*)|*.*';",
|
||||
-- write the pick as UTF-8: the console's OEM codepage would mangle
|
||||
-- non-ASCII names (Pokémon -> Pok\x82mon) and crash any text draw
|
||||
-- that shows them (#325)
|
||||
"if($d.ShowDialog() -eq 'OK'){[Console]::OutputEncoding=[Text.Encoding]::UTF8; [Console]::Write($d.FileName)}",
|
||||
-- copy the pick to a plain-ASCII temp name and answer with that:
|
||||
-- the console's OEM codepage would mangle a non-ASCII path
|
||||
-- (Pokémon -> Pok\x82mon) and io.open on Windows needs ANSI bytes,
|
||||
-- so returning the original name both crashed the notice draw and
|
||||
-- could never have opened the file (#325, #665)
|
||||
"if($d.ShowDialog() -eq 'OK'){",
|
||||
"$t=Join-Path $env:TEMP 'pokeport_rom_pick.gb';",
|
||||
"Copy-Item -LiteralPath $d.FileName -Destination $t -Force;",
|
||||
"[Console]::OutputEncoding=[Text.Encoding]::UTF8;",
|
||||
"[Console]::Write($t)}",
|
||||
})
|
||||
return commandOutput(
|
||||
'powershell -NoProfile -STA -Command "' .. script .. '"')
|
||||
@@ -477,7 +492,7 @@ end
|
||||
-- Returns the chosen absolute path or nil. Android uses love.system.pickFile
|
||||
-- ("mod") instead -- see RomImporter:chooseMod.
|
||||
local function chooseZip()
|
||||
local prompt = Strings("Choose a mod .zip")
|
||||
local prompt = shellSafe(Strings("Choose a mod .zip"))
|
||||
local platform = love.system.getOS()
|
||||
if platform == "OS X" then
|
||||
return commandOutput(
|
||||
@@ -517,7 +532,7 @@ end
|
||||
-- dialogs). Returns the chosen absolute path or nil. Android uses
|
||||
-- love.system.pickFile("sav") instead -- see RomImporter:chooseSaveImport.
|
||||
local function chooseSav()
|
||||
local prompt = Strings("Choose a .sav save file")
|
||||
local prompt = shellSafe(Strings("Choose a .sav save file"))
|
||||
local platform = love.system.getOS()
|
||||
if platform == "OS X" then
|
||||
return commandOutput(
|
||||
@@ -529,8 +544,14 @@ local function chooseSav()
|
||||
"$d=New-Object System.Windows.Forms.OpenFileDialog;",
|
||||
"$d.Title='" .. prompt .. "';",
|
||||
"$d.Filter='Game Boy save (*.sav)|*.sav|All files (*.*)|*.*';",
|
||||
-- UTF-8, like the ROM and mod pickers (#325)
|
||||
"if($d.ShowDialog() -eq 'OK'){[Console]::OutputEncoding=[Text.Encoding]::UTF8; [Console]::Write($d.FileName)}",
|
||||
-- copy the pick to a plain-ASCII temp name: io.open on Windows
|
||||
-- needs ANSI bytes, so a non-ASCII path (Pokémon -> Pok\x82mon)
|
||||
-- could never have been opened (#325, #665)
|
||||
"if($d.ShowDialog() -eq 'OK'){",
|
||||
"$t=Join-Path $env:TEMP 'pokeport_sav_pick.sav';",
|
||||
"Copy-Item -LiteralPath $d.FileName -Destination $t -Force;",
|
||||
"[Console]::OutputEncoding=[Text.Encoding]::UTF8;",
|
||||
"[Console]::Write($t)}",
|
||||
})
|
||||
return commandOutput(
|
||||
'powershell -NoProfile -STA -Command "' .. script .. '"')
|
||||
|
||||
Reference in New Issue
Block a user