From: Daniel Stenberg Date: Wed, 19 Oct 2022 09:17:35 +0000 (+0200) Subject: tool_xattr: save the original URL, not the final redirected one X-Git-Tag: curl-7_86_0~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3ab3c16b2ca1fedf9b1dc1a7d06e30b1c8408427;p=thirdparty%2Fcurl.git tool_xattr: save the original URL, not the final redirected one Adjusted test 1621 accordingly. Reported-by: Viktor Szakats Fixes #9766 Closes #9768 --- diff --git a/src/tool_operate.c b/src/tool_operate.c index 08e71fdfde..43c1c5e6c4 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -421,7 +421,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, } /* Set file extended attributes */ if(!result && config->xattr && outs->fopened && outs->stream) { - int rc = fwrite_xattr(curl, fileno(outs->stream)); + int rc = fwrite_xattr(curl, per->this_url, fileno(outs->stream)); if(rc) warnf(config->global, "Error setting extended attributes on '%s': %s\n", outs->filename, strerror(errno)); diff --git a/src/tool_xattr.c b/src/tool_xattr.c index b2a509d005..684aa939f8 100644 --- a/src/tool_xattr.c +++ b/src/tool_xattr.c @@ -48,26 +48,25 @@ static const struct xattr_mapping { * https://freedesktop.org/wiki/CommonExtendedAttributes/ */ { "user.xdg.referrer.url", CURLINFO_REFERER }, - { "user.xdg.origin.url", CURLINFO_EFFECTIVE_URL }, { "user.mime_type", CURLINFO_CONTENT_TYPE }, { NULL, CURLINFO_NONE } /* last element, abort here */ }; -/* returns TRUE if a new URL is returned, that then needs to be freed */ +/* returns a new URL that needs to be freed */ /* @unittest: 1621 */ #ifdef UNITTESTS -bool stripcredentials(char **url); +char *stripcredentials(const char *url); #else static #endif -bool stripcredentials(char **url) +char *stripcredentials(const char *url) { CURLU *u; CURLUcode uc; char *nurl; u = curl_url(); if(u) { - uc = curl_url_set(u, CURLUPART_URL, *url, 0); + uc = curl_url_set(u, CURLUPART_URL, url, 0); if(uc) goto error; @@ -85,57 +84,71 @@ bool stripcredentials(char **url) curl_url_cleanup(u); - *url = nurl; - return TRUE; + return nurl; } error: curl_url_cleanup(u); - return FALSE; + return NULL; } +static int xattr(int fd, + const char *attr, /* name of the xattr */ + const char *value) +{ + int err = 0; + if(value) { +#ifdef DEBUGBUILD + if(getenv("CURL_FAKE_XATTR")) { + printf("%s => %s\n", attr, value); + } + return 0; +#endif +#ifdef HAVE_FSETXATTR_6 + err = fsetxattr(fd, attr, value, strlen(value), 0, 0); +#elif defined(HAVE_FSETXATTR_5) + err = fsetxattr(fd, attr, value, strlen(value), 0); +#elif defined(__FreeBSD_version) || defined(__MidnightBSD_version) + { + ssize_t rc = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, + attr, value, strlen(value)); + /* FreeBSD's extattr_set_fd returns the length of the extended + attribute */ + err = (rc < 0 ? -1 : 0); + } +#endif + } + return err; +} /* store metadata from the curl request alongside the downloaded * file using extended attributes */ -int fwrite_xattr(CURL *curl, int fd) +int fwrite_xattr(CURL *curl, const char *url, int fd) { int i = 0; int err = 0; /* loop through all xattr-curlinfo pairs and abort on a set error */ - while(err == 0 && mappings[i].attr) { + while(!err && mappings[i].attr) { char *value = NULL; CURLcode result = curl_easy_getinfo(curl, mappings[i].info, &value); - if(!result && value) { - bool freeptr = FALSE; - if(CURLINFO_EFFECTIVE_URL == mappings[i].info) - freeptr = stripcredentials(&value); - if(value) { -#ifdef HAVE_FSETXATTR_6 - err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0, 0); -#elif defined(HAVE_FSETXATTR_5) - err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0); -#elif defined(__FreeBSD_version) || defined(__MidnightBSD_version) - { - ssize_t rc = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, - mappings[i].attr, value, strlen(value)); - /* FreeBSD's extattr_set_fd returns the length of the extended - attribute */ - err = (rc < 0 ? -1 : 0); - } -#endif - if(freeptr) - curl_free(value); - } - } + if(!result && value) + err = xattr(fd, mappings[i].attr, value); i++; } - + if(!err) { + char *nurl = stripcredentials(url); + if(!nurl) + return 1; + err = xattr(fd, "user.xdg.origin.url", nurl); + curl_free(nurl); + } return err; } #else -int fwrite_xattr(CURL *curl, int fd) +int fwrite_xattr(CURL *curl, const char *url, int fd) { (void)curl; + (void)url; (void)fd; return 0; diff --git a/src/tool_xattr.h b/src/tool_xattr.h index 8cc0204138..f107461a90 100644 --- a/src/tool_xattr.h +++ b/src/tool_xattr.h @@ -25,6 +25,6 @@ ***************************************************************************/ #include "tool_setup.h" -int fwrite_xattr(CURL *curl, int fd); +int fwrite_xattr(CURL *curl, const char *url, int fd); #endif /* HEADER_CURL_TOOL_XATTR_H */ diff --git a/tests/unit/unit1621.c b/tests/unit/unit1621.c index 0e6705d1c5..9147d4070d 100644 --- a/tests/unit/unit1621.c +++ b/tests/unit/unit1621.c @@ -47,7 +47,7 @@ UNITTEST_START UNITTEST_STOP #else -bool stripcredentials(char **url); +char *stripcredentials(const char *url); struct checkthis { const char *input; @@ -67,25 +67,22 @@ static const struct checkthis tests[] = { UNITTEST_START { - bool cleanup; - char *url; int i; int rc = 0; for(i = 0; tests[i].input; i++) { - url = (char *)tests[i].input; - cleanup = stripcredentials(&url); + const char *url = tests[i].input; + char *stripped = stripcredentials(url); printf("Test %u got input \"%s\", output: \"%s\"\n", - i, tests[i].input, url); + i, tests[i].input, stripped); - if(strcmp(tests[i].output, url)) { + if(stripped && strcmp(tests[i].output, stripped)) { fprintf(stderr, "Test %u got input \"%s\", expected output \"%s\"\n" " Actual output: \"%s\"\n", i, tests[i].input, tests[i].output, - url); + stripped); rc++; } - if(cleanup) - curl_free(url); + curl_free(stripped); } return rc; }