From 133bcced11d4427a9a279388a4099dc1dba55d06 Mon Sep 17 00:00:00 2001 From: Dorothy Date: Wed, 25 Feb 2026 12:53:08 +0530 Subject: [PATCH] [212_2703] Fix gs path quoting for paths with spaces on macOS --- devel/212_2703.md | 22 ++++++++++++++++++++ src/Plugins/Ghostscript/gs_utilities.cpp | 26 +++++++++++++----------- 2 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 devel/212_2703.md diff --git a/devel/212_2703.md b/devel/212_2703.md new file mode 100644 index 0000000000..c20c7f6256 --- /dev/null +++ b/devel/212_2703.md @@ -0,0 +1,22 @@ +# 212_2703 + +## 如何测试 +Open Mogan STEM, insert a PS/EPS image, and verify it renders correctly. +To reproduce the bug: use a macOS account whose full name contains a space +(e.g. "John Doe"), then insert a PS/EPS image. + +## 2026/02/25 Fix gs path quoting for paths with spaces on macOS + +### What +In `gs_utilities.cpp`, replaced `sys_concretize(url)` with `raw_quote(concretize(url))` +for all file paths passed to Ghostscript commands. + +### Why +`sys_concretize` backslash-escapes spaces (e.g. `/tmp/path\ with\ spaces/file.eps`), +which the shell handles fine for standalone args. But GS parses option values like +`-sOutputFile=...` as raw strings and does not interpret the backslash, so it splits +at the space. Double-quoting with `raw_quote` fixes this. + +### How +Replace `sys_concretize(u)` with `raw_quote(concretize(u))` in `gs_utilities.cpp`. +Same pattern already used in `gs_prefix()` on Windows. diff --git a/src/Plugins/Ghostscript/gs_utilities.cpp b/src/Plugins/Ghostscript/gs_utilities.cpp index 63281af2cd..5357a80188 100644 --- a/src/Plugins/Ghostscript/gs_utilities.cpp +++ b/src/Plugins/Ghostscript/gs_utilities.cpp @@ -104,7 +104,7 @@ gs_image_size (url image, int& w_pt, int& h_pt) { // reading a ps page // real eps pages with proper bounding boxes have been recognized // before this and will have their BoundingBox respected - cmd << sys_concretize (image); + cmd << raw_quote (concretize (image)); lolly::system::check_stderr (cmd, buf); if (DEBUG_CONVERT) debug_convert << "gs cmd :" << cmd << LF << "answer :" << buf; @@ -159,18 +159,20 @@ gs_PDFimage_size (url image, int& w_pt, int& h_pt) { string buf; string cmd= gs_prefix (); if (gs_version () >= 9.50) - cmd << "--permit-file-read=" << sys_concretize (image) << " "; + cmd << "--permit-file-read=" << raw_quote (concretize (image)) << " "; cmd << "-dNODISPLAY -q -sFile="; - cmd << sys_concretize (image); + cmd << raw_quote (concretize (image)); cmd << " pdf_info.ps"; buf= eval_system (cmd); if (occurs ("Unrecoverable error", buf)) { cmd= gs_prefix (); if (gs_version () >= 9.50) - cmd << "--permit-file-read=" << sys_concretize (image) << " "; + cmd << "--permit-file-read=" << raw_quote (concretize (image)) << " "; cmd << "-dNODISPLAY -q -sFile="; - cmd << sys_concretize (image); - cmd << " " << sys_concretize ("$TEXMACS_PATH/misc/convert/pdf_info.ps"); + cmd << raw_quote (concretize (image)); + cmd << " " + << raw_quote ( + concretize (url ("$TEXMACS_PATH/misc/convert/pdf_info.ps"))); buf= eval_system (cmd); } if (DEBUG_CONVERT) @@ -241,14 +243,14 @@ gs_to_eps (url image, cmd= gs_prefix (); cmd << "-dQUIET -dNOPAUSE -dBATCH -dSAFER "; cmd << "-sDEVICE=" << eps_device (); - cmd << " -sOutputFile=" << sys_concretize (eps) << " "; + cmd << " -sOutputFile=" << raw_quote (concretize (eps)) << " "; if (suffix (image) == "pdf") { image_size (image, bx2, by2); bx1= by1= 0; cmd << "-dUseCropBox " << " -dDEVICEWIDTHPOINTS=" << as_string (bx2) << " -dDEVICEHEIGHTPOINTS=" << as_string (by2) << " " - << sys_concretize (image); + << raw_quote (concretize (image)); } else { ps_bounding_box (image, bx1, by1, bx2, by2); @@ -256,7 +258,7 @@ gs_to_eps (url image, << " -dDEVICEHEIGHTPOINTS=" << as_string (by2 - by1) << " "; // don't use -dEPSCrop which works incorrectly if (bx1 != 0 || by1 != 0) cmd << "-c \" " << as_string (-bx1) << " " << as_string (-by1) - << " translate gsave \" " << sys_concretize (image) + << " translate gsave \" " << raw_quote (concretize (image)) << " -c \" grestore \""; } string ans= eval_system (cmd); @@ -283,8 +285,8 @@ gs_to_ps (url doc, url ps, bool landscape, double paper_h, double paper_w) { << " -dDEVICEHEIGHTPOINTS=" << as_string ((int) (28.36 * paper_h + 0.5)); - cmd << " -sOutputFile=" << sys_concretize (ps) << " "; - cmd << sys_concretize (doc); + cmd << " -sOutputFile=" << raw_quote (concretize (ps)) << " "; + cmd << raw_quote (concretize (doc)); cmd << " -c \"[ /Title (" << as_string (tail (ps)) << ") /DOCINFO pdfmark\" "; // NOTE: when converting from pdf to ps the title of the document is @@ -301,6 +303,6 @@ void tm_gs (url image) { string cmd= gs_prefix (); cmd << "-q -sDEVICE=x11alpha -dBATCH -dNOPAUSE -dSAFER -dNOEPS "; - cmd << sys_concretize (image); + cmd << raw_quote (concretize (image)); lolly::system::call (cmd); }