summaryrefslogtreecommitdiffstats
path: root/util/cutils.c
diff options
context:
space:
mode:
authorPeter Maydell2022-07-14 19:14:12 +0200
committerPeter Maydell2022-07-14 19:14:12 +0200
commit285f64fcbf86dac2be6dbd0a8a32872bcff3cacb (patch)
tree1a30f398cbd4007b5ce8d955e24890eec84c90a6 /util/cutils.c
parentMerge tag 'qga-win32-pull-2022-07-13' of github.com:kostyanf14/qemu into staging (diff)
parentpc-bios/s390-ccw: add -Wno-array-bounds (diff)
downloadqemu-285f64fcbf86dac2be6dbd0a8a32872bcff3cacb.tar.gz
qemu-285f64fcbf86dac2be6dbd0a8a32872bcff3cacb.tar.xz
qemu-285f64fcbf86dac2be6dbd0a8a32872bcff3cacb.zip
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* SCSI fuzzing fix (Mauro) * pre-install data files in the build directory (Akihiko) * SCSI fixes for Mac OS (Mark) # gpg: Signature made Wed 13 Jul 2022 15:59:00 BST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * tag 'for-upstream' of https://gitlab.com/bonzini/qemu: pc-bios/s390-ccw: add -Wno-array-bounds q800: add default vendor and product information for scsi-cd devices q800: add default vendor and product information for scsi-hd devices scsi-disk: allow MODE SELECT block descriptor to set the block size scsi-disk: allow the MODE_PAGE_R_W_ERROR AWRE bit to be changeable for CDROM drives q800: implement compat_props to enable quirk_mode_page_truncated for scsi-cd devices scsi-disk: add SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED quirk for Macintosh scsi-disk: add FORMAT UNIT command q800: implement compat_props to enable quirk_mode_page_vendor_specific_apple for scsi devices scsi-disk: add SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE quirk for Macintosh q800: implement compat_props to enable quirk_mode_sense_rom_use_dbd for scsi-cd devices scsi-disk: add SCSI_DISK_QUIRK_MODE_SENSE_ROM_USE_DBD quirk for Macintosh q800: implement compat_props to enable quirk_mode_page_apple_vendor for scsi-cd devices scsi-disk: add MODE_PAGE_APPLE_VENDOR quirk for Macintosh scsi-disk: add new quirks bitmap to SCSIDiskState meson: Prefix each element of firmware path module: Use bundle mechanism datadir: Use bundle mechanism cutils: Introduce bundle mechanism scsi/lsi53c895a: really fix use-after-free in lsi_do_msgout (CVE-2022-0216) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/cutils.c')
-rw-r--r--util/cutils.c68
1 files changed, 47 insertions, 21 deletions
diff --git a/util/cutils.c b/util/cutils.c
index 6d04e52907..8199dac598 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -35,6 +35,11 @@
#include <sys/sysctl.h>
#endif
+#ifdef G_OS_WIN32
+#include <pathcch.h>
+#include <wchar.h>
+#endif
+
#include "qemu/ctype.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
@@ -1074,31 +1079,52 @@ char *get_relocated_path(const char *dir)
/* Fail if qemu_init_exec_dir was not called. */
assert(exec_dir[0]);
- if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
- return g_strdup(dir);
- }
result = g_string_new(exec_dir);
+ g_string_append(result, "/qemu-bundle");
+ if (access(result->str, R_OK) == 0) {
+#ifdef G_OS_WIN32
+ size_t size = mbsrtowcs(NULL, &dir, 0, &(mbstate_t){0}) + 1;
+ PWSTR wdir = g_new(WCHAR, size);
+ mbsrtowcs(wdir, &dir, size, &(mbstate_t){0});
+
+ PCWSTR wdir_skipped_root;
+ PathCchSkipRoot(wdir, &wdir_skipped_root);
+
+ size = wcsrtombs(NULL, &wdir_skipped_root, 0, &(mbstate_t){0});
+ char *cursor = result->str + result->len;
+ g_string_set_size(result, result->len + size);
+ wcsrtombs(cursor, &wdir_skipped_root, size + 1, &(mbstate_t){0});
+ g_free(wdir);
+#else
+ g_string_append(result, dir);
+#endif
+ } else if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
+ g_string_assign(result, dir);
+ } else {
+ g_string_assign(result, exec_dir);
+
+ /* Advance over common components. */
+ len_dir = len_bindir = prefix_len;
+ do {
+ dir += len_dir;
+ bindir += len_bindir;
+ dir = next_component(dir, &len_dir);
+ bindir = next_component(bindir, &len_bindir);
+ } while (len_dir && len_dir == len_bindir && !memcmp(dir, bindir, len_dir));
+
+ /* Ascend from bindir to the common prefix with dir. */
+ while (len_bindir) {
+ bindir += len_bindir;
+ g_string_append(result, "/..");
+ bindir = next_component(bindir, &len_bindir);
+ }
- /* Advance over common components. */
- len_dir = len_bindir = prefix_len;
- do {
- dir += len_dir;
- bindir += len_bindir;
- dir = next_component(dir, &len_dir);
- bindir = next_component(bindir, &len_bindir);
- } while (len_dir && len_dir == len_bindir && !memcmp(dir, bindir, len_dir));
-
- /* Ascend from bindir to the common prefix with dir. */
- while (len_bindir) {
- bindir += len_bindir;
- g_string_append(result, "/..");
- bindir = next_component(bindir, &len_bindir);
+ if (*dir) {
+ assert(G_IS_DIR_SEPARATOR(dir[-1]));
+ g_string_append(result, dir - 1);
+ }
}
- if (*dir) {
- assert(G_IS_DIR_SEPARATOR(dir[-1]));
- g_string_append(result, dir - 1);
- }
return g_string_free(result, false);
}