-
Notifications
You must be signed in to change notification settings - Fork 115
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
Fix Visicut calling inkscape in an AppImage. #721
base: master
Are you sure you want to change the base?
Conversation
In Ubuntu 20.04, this worked flawlessly. But only by chance. We use libraries from the host system, together with the binary inside the mounted appimage. in Ubintu 22.04, this crashes: /tmp/.mount_inkscaYGPL8G/usr/bin/inkscape --version /tmp/.mount_inkscaYGPL8G/usr/bin/inkscape: error while loading shared libraries: libboost_filesystem.so.1.71.0: cannot open shared object file: No such file or directory The fix is to not call the binary directly, but the AppRun scrit, which nicely prepares the environment. AppRun also prints a message for the user to stdout, (instead of stderr). We now need to filter this, when parsing output from e.g. --version: /tmp/.mount_inkscaYGPL8G/AppRun --version 2>/dev/null You should not use AppImage in production, but you can speedup the AppImage by following this guide: https://inkscape.org/learn/appimage/ Inkscape 1.3.2 (091e20e, 2023-11-25)
dirname() should be fine to. It is more readable. Thanks! (not sure if introducing a new apprun_path variable contributes to readability though ...) But I don't mind. Co-authored-by: TheAssassin <[email protected]>
I'll open a separate PR to fix the issues in the linux-checkinstall CI. |
Fix for the CI problems available in #722. |
Please also report the stdout pollution as an upstream issue with Inkscape. We are probably not the only one affected by that. ( Side topics, not really relevant to this PR: What about the other combinations and directions - does calling Visicut from the AppImage Inkscape work correctly, even with all the AppImage environment variables? What if VisiCut is also an AppImage? ) |
If someone opens an issue upstream, please ask them to just |
Yes, I believe most real-life combinations work. I have especially tested the case where both, Inkscape and VisiCut are AppImages. |
This is broken currently and will be working once this has been merged. |
INKSCAPEBIN = apprun_path | ||
for parent in Path(INKSCAPEBIN).parents: | ||
apprun = parent / "AppRun" | ||
if apprun.is_file() and os.access(apprun, os.X_OK): |
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.
I like this os.access
check, it's very compact. pathlib
should have a shortcut for that.
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.
Maybe only checking is_file() alone is even more compact? An inkscape AppImage that has an 'AppRun' file which has no execute bits, or is mounted without exec, or suffering from a security policy, or whatever ... is out of scope here anyway.
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.
Just failing silently is not the best idea. Your algorithm can still cross mountpoints (that's what the is_mount
check was there for before) and I can imagine a bunch of false positive detections of AppRun
s in that case. For instance, in some occasions, AppDirs can be integrated in each other (lazy approach but it works, I use that myself occasionally). In such a case, the execute bit on some AppRun
in the chain might not be set. Also, AppImages can be extracted and copied to devices that do not have the executable bit set, etc.
The check is fine and it's good to have it. In fact, security wise, we should add the mountpoint check and abort once it's crossed. To do so, this should be appended to the for
's body:
if parent.is_mount():
break
Security (i.e., preventing critical issues) and safety (i.e., keeping users from experiencing weird behavior) always add a bit of verbosity to the code, but in the end, it's always worth it. We'd have some good reasons to throw exceptions here even. But that'd bloat this PR. I think in its current form, it's a reasonably solid implementation and I don't see any attack vector (without thinking about it for more than 5 minutes).
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.
I found an INKSCAPE_COMMAND
environment variable that seems to point to the AppRun file. Can you check if we can use this instead? First guess:
INKSCAPEBIN = os.environ.get("INKSCAPE_COMMAND") or which("inkscape", [INKSCAPEDIR])
This would avoid the potential problems.
INKSCAPEBIN = apprun_path | ||
for parent in Path(INKSCAPEBIN).parents: | ||
apprun = parent / "AppRun" | ||
if apprun.is_file() and os.access(apprun, os.X_OK): |
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.
I found an INKSCAPE_COMMAND
environment variable that seems to point to the AppRun file. Can you check if we can use this instead? First guess:
INKSCAPEBIN = os.environ.get("INKSCAPE_COMMAND") or which("inkscape", [INKSCAPEDIR])
This would avoid the potential problems.
What does "found" mean? Is that an officially supported environment variable provided by the Inkscape code? Is it an AppImage-specific feature? |
For Inkscape 1.3.x and 1.4.x (current / upcoming release), the AppImage sets For Inkscape 1.5.x (development branch) the AppImage is currently broken and fails to launch Python, so it is not possible to test. https://gitlab.com/inkscape/inkscape/-/issues/4851 Inkscape's Once we drop support for AppImage-Inkscape < 1.3 and normal Inkscape < 1.0 (used e.g. on Ubuntu 20.04) we could throw out half of our extension code and instead use |
In Ubuntu 20.04, this worked flawlessly. But only by chance. We use libraries from the host system, together with the binary inside the mounted appimage. in Ubintu 22.04, this crashes:
/tmp/.mount_inkscaYGPL8G/usr/bin/inkscape --version
/tmp/.mount_inkscaYGPL8G/usr/bin/inkscape: error while loading shared libraries: libboost_filesystem.so.1.71.0: cannot open shared object file: No such file or directory
The fix is to not call the binary directly, but the AppRun script, which nicely prepares the environment. But then, AppRun also prints a message for the user to stdout, (instead of stderr). We now need to filter this, when parsing output from e.g. --version:
/tmp/.mount_inkscaYGPL8G/AppRun --version 2>/dev/null
You should not use AppImage in production, but you can speedup the AppImage by following this guide: https://inkscape.org/learn/appimage/
Inkscape 1.3.2 (091e20e, 2023-11-25)