-
Notifications
You must be signed in to change notification settings - Fork 82
[212_2703] Fix gs path quoting for paths with spaces on macOS #2859
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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"; | ||
|
Comment on lines
161
to
165
|
||
| 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,22 +243,22 @@ 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") { | ||
|
Comment on lines
244
to
247
|
||
| 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); | ||
| cmd << " -dDEVICEWIDTHPOINTS=" << as_string (bx2 - bx1) | ||
| << " -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\" "; | ||
|
Comment on lines
+288
to
290
|
||
|
|
||
| // 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); | ||
|
Comment on lines
304
to
307
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
raw_quote(concretize(image))is not shell-safe on macOS/Linux:raw_quotejust wraps in double quotes and does not escape$, backticks, or". Sincelolly::system::calluseswordexp(..., flags=0)(command substitution enabled), a crafted filename could trigger expansion/command execution. For positional file args,sys_concretize(image)already handles spaces via backslash-escaping while also escaping metacharacters; consider keepingsys_concretizehere and only changing the truly GS-option-value cases, or introduce a dedicated safe quoting/escaping helper forwordexp.