[pacman-dev] [PATCH] libalpm: check for duplicate filenames

Allan McRae allan at archlinux.org
Sun May 9 13:09:31 UTC 2021


On 21/4/21 9:03 pm, morganamilo wrote:
> This partially fixes FS#67850
> 
> It fixes the case for -S'ing packages but not -U'ing urls.
> 
> morganamilo at Octavia dup ~git/pacman % sudo ./build/pacman -S a/a b/b

just the command is good.

> resolving dependencies...
> error: a and b have the same filename: a-1-1-any.pkg.tar.zst

error: packages a and b

> error: failed to prepare transaction (duplicate filename)
> 
> diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
> index 833df829..ccf2edc2 100644
> --- a/lib/libalpm/alpm.h
> +++ b/lib/libalpm/alpm.h
> @@ -257,6 +257,8 @@ typedef enum _alpm_errno_t {
>  	ALPM_ERR_TRANS_NULL,
>  	/** Duplicate target in transaction */
>  	ALPM_ERR_TRANS_DUP_TARGET,
> +	/** Duplicate filename in transaction */
> +	ALPM_ERR_TRANS_DUP_FILENAME,
>  	/** A transaction has not been initialized */
>  	ALPM_ERR_TRANS_NOT_INITIALIZED,
>  	/** Transaction has not been prepared */

OK

> diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c
> index c6f19599..c06d091a 100644
> --- a/lib/libalpm/error.c
> +++ b/lib/libalpm/error.c
> @@ -90,6 +90,8 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
>  			return _("transaction not initialized");
>  		case ALPM_ERR_TRANS_DUP_TARGET:
>  			return _("duplicate target");
> +		case ALPM_ERR_TRANS_DUP_FILENAME:
> +			return _("duplicate filename");

OK

>  		case ALPM_ERR_TRANS_NOT_INITIALIZED:
>  			return _("transaction not initialized");
>  		case ALPM_ERR_TRANS_NOT_PREPARED:
> diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
> index 7fa50a13..73e9e77d 100644
> --- a/lib/libalpm/sync.c
> +++ b/lib/libalpm/sync.c
> @@ -464,6 +464,25 @@ int _alpm_sync_prepare(alpm_handle_t *handle, alpm_list_t **data)
>  			}
>  		}
>  
> +		/* Ensure two packages don't have the same filename */
> +		for(i = resolved; i; i = i->next) {
> +			alpm_pkg_t *pkg1 = i->data;
> +			for(j = i->next; j; j = j->next) {
> +				alpm_pkg_t *pkg2 = j->data;
> +				if(strcmp(pkg1->filename, pkg2->filename) == 0) {
> +					alpm_list_free(resolved);
> +					ret = -1;
> +					handle->pm_errno = ALPM_ERR_TRANS_DUP_FILENAME;
> +					_alpm_log(handle, ALPM_LOG_ERROR, _("%s and %s have the same filename: %s\n"),

packages %s and %s have ...

> +						pkg1->name, pkg2->name, pkg1->filename);
> +				}
> +			}
> +		}
> +
> +		if(ret != 0) {
> +			goto cleanup;
> +		}
> +
>  		/* Set DEPEND reason for pulled packages */
>  		for(i = resolved; i; i = i->next) {
>  			alpm_pkg_t *pkg = i->data;
> diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
> index c6ec7eea..4cee603c 100644
> --- a/lib/libalpm/trans.c
> +++ b/lib/libalpm/trans.c
> @@ -122,7 +122,7 @@ int SYMEXPORT alpm_trans_prepare(alpm_handle_t *handle, alpm_list_t **data)
>  			/* pm_errno is set by _alpm_remove_prepare() */
>  			return -1;
>  		}
> -	}	else {
> +	} else {

unrelated.  I'll accept that as a separate patch.

>  		if(_alpm_sync_prepare(handle, data) == -1) {
>  			/* pm_errno is set by _alpm_sync_prepare() */
>  			return -1;
> 


More information about the pacman-dev mailing list