-
Notifications
You must be signed in to change notification settings - Fork 85
[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 |
|---|---|---|
|
|
@@ -19,6 +19,30 @@ | |
| #include "sys_utils.hpp" | ||
| #include "tm_file.hpp" | ||
|
|
||
| // Quote a path for use in Ghostscript commands on macOS/Linux. | ||
| // Wraps in double quotes (to preserve spaces in GS option values like | ||
| // -sOutputFile=) and escapes $, backticks, ", and \ so that wordexp | ||
| // does not perform variable/command expansion on the result. | ||
| static string | ||
| gs_path_quote (string s) { | ||
| string r= "\""; | ||
| int n= N (s); | ||
| for (int i= 0; i < n; i++) { | ||
| switch (s[i]) { | ||
| case '$': | ||
| case '`': | ||
| case '"': | ||
| case '\\': | ||
| r << '\\' << s[i]; | ||
| break; | ||
| default: | ||
| r << s[i]; | ||
| } | ||
| } | ||
| r << "\""; | ||
| return r; | ||
| } | ||
|
|
||
| static string | ||
| gs_executable () { | ||
| eval ("(use-modules (binary gs))"); | ||
|
|
@@ -104,7 +128,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 << gs_path_quote (concretize (image)); | ||
| lolly::system::check_stderr (cmd, buf); | ||
| if (DEBUG_CONVERT) | ||
| debug_convert << "gs cmd :" << cmd << LF << "answer :" << buf; | ||
|
|
@@ -159,18 +183,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=" << gs_path_quote (concretize (image)) << " "; | ||
| cmd << "-dNODISPLAY -q -sFile="; | ||
| cmd << sys_concretize (image); | ||
| cmd << gs_path_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=" << gs_path_quote (concretize (image)) << " "; | ||
| cmd << "-dNODISPLAY -q -sFile="; | ||
| cmd << sys_concretize (image); | ||
| cmd << " " << sys_concretize ("$TEXMACS_PATH/misc/convert/pdf_info.ps"); | ||
| cmd << gs_path_quote (concretize (image)); | ||
| cmd << " " | ||
| << gs_path_quote ( | ||
| concretize (url ("$TEXMACS_PATH/misc/convert/pdf_info.ps"))); | ||
| buf= eval_system (cmd); | ||
| } | ||
| if (DEBUG_CONVERT) | ||
|
|
@@ -241,22 +267,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=" << gs_path_quote (concretize (eps)) << " "; | ||
| if (suffix (image) == "pdf") { | ||
|
Comment on lines
268
to
271
|
||
| image_size (image, bx2, by2); | ||
| bx1= by1= 0; | ||
| cmd << "-dUseCropBox " | ||
| << " -dDEVICEWIDTHPOINTS=" << as_string (bx2) | ||
| << " -dDEVICEHEIGHTPOINTS=" << as_string (by2) << " " | ||
| << sys_concretize (image); | ||
| << gs_path_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 \" " << gs_path_quote (concretize (image)) | ||
| << " -c \" grestore \""; | ||
| } | ||
| string ans= eval_system (cmd); | ||
|
|
@@ -283,8 +309,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=" << gs_path_quote (concretize (ps)) << " "; | ||
| cmd << gs_path_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 +327,6 @@ void | |
| tm_gs (url image) { | ||
| string cmd= gs_prefix (); | ||
| cmd << "-q -sDEVICE=x11alpha -dBATCH -dNOPAUSE -dSAFER -dNOEPS "; | ||
| cmd << sys_concretize (image); | ||
| cmd << gs_path_quote (concretize (image)); | ||
| lolly::system::call (cmd); | ||
|
Comment on lines
328
to
331
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.