From 45b547dcc32dcb85f171d6ff6456b6216042b90c Mon Sep 17 00:00:00 2001 From: Shivani Agarwal Date: Tue, 26 Sep 2023 06:55:02 +0000 Subject: [PATCH] tdnf: Add check to identify duplicate repo id --- client/defines.h | 1 + client/repolist.c | 19 ++++++++++++++++++- include/tdnferror.h | 2 ++ pytests/tests/test_baseurls.py | 2 +- pytests/tests/test_repolist.py | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/client/defines.h b/client/defines.h index bf3c40d5..fd8fa5d8 100644 --- a/client/defines.h +++ b/client/defines.h @@ -232,6 +232,7 @@ typedef enum {ERROR_TDNF_INVALID_INPUT, "ERROR_TDNF_INVALID_INPUT", "Invalid input."},\ {ERROR_TDNF_CACHE_DISABLED, "ERROR_TDNF_CACHE_DISABLED", "cache only is set, but no repo data found"},\ {ERROR_TDNF_CACHE_DIR_OUT_OF_DISK_SPACE, "ERROR_TDNF_CACHE_DIR_OUT_OF_DISK_SPACE", "Insufficient disk space at cache directory /var/cache/tdnf (unless specified differently in config). Try freeing space first."},\ + {ERROR_TDNF_DUPLICATE_REPO_ID, "ERROR_TDNF_DUPLICATE_REPO_ID", "Duplicate repo id"}, \ {ERROR_TDNF_EVENT_CTXT_ITEM_NOT_FOUND, "ERROR_TDNF_EVENT_CTXT_ITEM_NOT_FOUND", "An event context item was not found. This is usually related to plugin events. Try --noplugins to deactivate all plugins or --disableplugin= to deactivate a specific one. You can permanently deactivate an offending plugin by setting enable=0 in the plugin config file."},\ {ERROR_TDNF_EVENT_CTXT_ITEM_INVALID_TYPE, "ERROR_TDNF_EVENT_CTXT_ITEM_INVALID_TYPE", "An event item type had a mismatch. This is usually related to plugin events. Try --noplugins to deactivate all plugins or --disableplugin= to deactivate a specific one. You can permanently deactivate an offending plugin by setting enable=0 in the plugin config file."},\ {ERROR_TDNF_NO_GPGKEY_CONF_ENTRY, "ERROR_TDNF_NO_GPGKEY_CONF_ENTRY", "gpgkey entry is missing for this repo. please add gpgkey in repo file or use --nogpgcheck to ignore."}, \ diff --git a/client/repolist.c b/client/repolist.c index 1bb1168f..1b95680e 100644 --- a/client/repolist.c +++ b/client/repolist.c @@ -28,6 +28,8 @@ TDNFLoadRepoData( DIR *pDir = NULL; struct dirent *pEnt = NULL; char **ppszUrlIdTuple = NULL; + PTDNF_REPO_DATA pRepoParsePre = NULL; + PTDNF_REPO_DATA pRepoParseNext = NULL; if(!pTdnf || !pTdnf->pConf || !pTdnf->pArgs || !ppReposAll) { @@ -115,12 +117,27 @@ TDNFLoadRepoData( TDNF_SAFE_FREE_MEMORY(pszRepoFilePath); pszRepoFilePath = NULL; - /* may have added multiple repos, go to last one */ while (*ppRepoNext) ppRepoNext = &((*ppRepoNext)->pNext); } + pRepoParsePre = pReposAll; + + while (pRepoParsePre != NULL && pRepoParsePre->pNext != NULL) { + pRepoParseNext = pRepoParsePre; + + while (pRepoParseNext->pNext != NULL) { + if (!strcmp(pRepoParsePre->pszId, pRepoParseNext->pNext->pszId)) { + dwError = ERROR_TDNF_DUPLICATE_REPO_ID; + BAIL_ON_TDNF_ERROR(dwError); + } + else + pRepoParseNext = pRepoParseNext->pNext; + } + pRepoParsePre = pRepoParsePre->pNext; + } + *ppReposAll = pReposAll; cleanup: if(pDir) diff --git a/include/tdnferror.h b/include/tdnferror.h index 7e6246f7..c9349a06 100644 --- a/include/tdnferror.h +++ b/include/tdnferror.h @@ -72,6 +72,8 @@ extern "C" { #define ERROR_TDNF_DOWNGRADE_NOT_ALLOWED 1035 // cache directory out of memory #define ERROR_TDNF_CACHE_DIR_OUT_OF_DISK_SPACE 1036 +// There are duplicate repo id +#define ERROR_TDNF_DUPLICATE_REPO_ID 1037 //curl errors #define ERROR_TDNF_CURL_INIT 1200 diff --git a/pytests/tests/test_baseurls.py b/pytests/tests/test_baseurls.py index 7ebeb847..58b19cab 100644 --- a/pytests/tests/test_baseurls.py +++ b/pytests/tests/test_baseurls.py @@ -33,7 +33,7 @@ def teardown_test(utils): def test_multiple_baseurls(utils): - reponame = TESTREPO + reponame = REPONAME workdir = WORKDIR utils.makedirs(workdir) diff --git a/pytests/tests/test_repolist.py b/pytests/tests/test_repolist.py index 2b0e4229..1abfbf38 100644 --- a/pytests/tests/test_repolist.py +++ b/pytests/tests/test_repolist.py @@ -50,6 +50,8 @@ def setup_test(utils): def teardown_test(utils): os.remove(os.path.join(utils.config['repo_path'], 'yum.repos.d', 'foo.repo')) os.remove(os.path.join(utils.config['repo_path'], 'yum.repos.d', 'bar.repo')) + os.remove(os.path.join(utils.config['repo_path'], "yum.repos.d", 'test.repo')) + os.remove(os.path.join(utils.config['repo_path'], "yum.repos.d", 'test1.repo')) def find_repo(repolist, id): @@ -126,3 +128,35 @@ def test_repolist_invalid(utils): def test_repolist_memcheck(utils): ret = utils.run_memcheck(['tdnf', 'repolist']) assert ret['retval'] == 0 + + +# multiple repoid +def test_multiple_repoid(utils): + reponame = 'test.repo' + repofile_test = os.path.join(utils.config['repo_path'], 'yum.repos.d', reponame) + utils.edit_config( + { + 'name': 'Test Repo', + 'enabled': '1', + 'baseurl': 'http://pkgs.test.org/test' + }, + section='test', + filename=repofile_test + ) + + reponame = 'test1.repo' + repofile_test1 = os.path.join(utils.config['repo_path'], 'yum.repos.d', reponame) + utils.edit_config( + { + 'name': 'Test Repo', + 'enabled': '1', + 'baseurl': 'http://pkgs.test1.org/test1' + }, + section='test', + filename=repofile_test1 + ) + + ret = utils.run(['tdnf', + '--disablerepo=*', '--enablerepo={}'.format(reponame), + 'makecache']) + assert ret['retval'] == 1037