From b64c81d0d0f388aed10a543ed8d0a2f6fff478b9 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Thu, 20 Oct 2022 12:53:55 -0400 Subject: [PATCH v1] pg_basebackup: When -Tx=y is used, weaken absolute path check on x. Specifically, if x looks like it could be an absolute pathname on either Windows or Linux, assume it is. The previous code checked using the local machine's rules, but the remote server need not be running the same OS. --- src/bin/pg_basebackup/pg_basebackup.c | 20 ++++++++++++---- src/include/port.h | 34 +++++++++++++++------------ 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index 7d17f8b33e..22836ca01a 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -340,12 +340,22 @@ tablespace_list_append(const char *arg) pg_fatal("invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"", arg); /* - * This check isn't absolutely necessary. But all tablespaces are created - * with absolute directories, so specifying a non-absolute path here would - * just never match, possibly confusing users. It's also good to be - * consistent with the new_dir check. + * All tablespaces are created with absolute directories, so specifying a + * non-absolute path here would just never match, possibly confusing users. + * Since we don't know whether the remote side is Windows or not, and it + * might be different than the local side, permit any path that could be + * absolute under either set of rules. + * + * (There is little practical risk of confusion here, because someone + * running entirely on Linux isn't likely to have a relative path that + * begins with a backslash or something that looks like a drive + * specification. If they do, and they also incorrectly believe that + * a relative path is acceptable here, we'll silently fail to warn them + * of their mistake, and the -T option will just not get applied, same + * as if they'd specified -T for a nonexistent tablespace.) */ - if (!is_absolute_path(cell->old_dir)) + if (!is_nonwindows_absolute_path(cell->old_dir) && + !is_windows_absolute_path(cell->old_dir)) pg_fatal("old directory is not an absolute path in tablespace mapping: %s", cell->old_dir); diff --git a/src/include/port.h b/src/include/port.h index 69d8818d61..79a41b4c7f 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -78,28 +78,32 @@ extern void get_parent_directory(char *path); extern char **pgfnames(const char *path); extern void pgfnames_cleanup(char **filenames); -/* - * is_absolute_path - * - * By making this a macro we avoid needing to include path.c in libpq. - */ -#ifndef WIN32 -#define IS_DIR_SEP(ch) ((ch) == '/') - -#define is_absolute_path(filename) \ +#define IS_NONWINDOWS_DIR_SEP(ch) ((ch) == '/') +#define is_nonwindows_absolute_path(filename) \ ( \ - IS_DIR_SEP((filename)[0]) \ + IS_NONWINDOWS_DIR_SEP((filename)[0]) \ ) -#else -#define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\') +#define IS_WINDOWS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\') /* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */ -#define is_absolute_path(filename) \ +#define is_windows_absolute_path(filename) \ ( \ - IS_DIR_SEP((filename)[0]) || \ + IS_WINDOWS_DIR_SEP((filename)[0]) || \ (isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \ - IS_DIR_SEP((filename)[2])) \ + IS_WINDOWS_DIR_SEP((filename)[2])) \ ) + +/* + * is_absolute_path and IS_DIR_SEP + * + * By using macros here we avoid needing to include path.c in libpq. + */ +#ifndef WIN32 +#define IS_DIR_SEP IS_NONWINDOWS_DIR_SEP +#define is_absolute_path is_nonwindows_absolute_path +#else +#define IS_DIR_SEP IS_WINDOWS_DIR_SEP +#define is_absolute_path is_windows_absolute_path #endif /* -- 2.24.3 (Apple Git-128)