tool_xattr: save the original URL, not the final redirected one

Adjusted test 1621 accordingly.

Reported-by: Viktor Szakats
Fixes #9766
Closes #9768
This commit is contained in:
Daniel Stenberg 2022-10-19 11:17:35 +02:00
parent 873cc38e89
commit 3ab3c16b2c
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 56 additions and 46 deletions

View File

@ -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));

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}