mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-03 14:52:21 +02:00
Fix issue when listing directories recursively with a filter.
While recursing and filtering, if the last entry in a directory was another directory containing entries then the parent list would get freed too early, causing a double free error or segfault. Fix by ensuring that the completed list is at the top of the stack before freeing it. This will defer freeing parent lists until the contents of paths have been processed.
This commit is contained in:
parent
08a44be4c3
commit
c39c9f220e
@ -29,6 +29,19 @@
|
||||
|
||||
<p>Fix incorrect time expiration being used for non-default repos.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<github-issue id="1870"/>
|
||||
<github-pull-request id="1871"/>
|
||||
|
||||
<release-item-contributor-list>
|
||||
<release-item-ideator id="efremov.egor"/>
|
||||
<release-item-contributor id="david.steele"/>
|
||||
<release-item-reviewer id="stephen.frost"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Fix issue when listing directories recursively with a filter.</p>
|
||||
</release-item>
|
||||
</release-bug-list>
|
||||
|
||||
<release-feature-list>
|
||||
|
@ -244,7 +244,11 @@ storageItrMore(StorageIterator *const this)
|
||||
}
|
||||
|
||||
// If no more info then free the list. This check is required because we may break out of the above loop early.
|
||||
if (listInfo->listIdx >= storageLstSize(listInfo->list))
|
||||
//
|
||||
// Only free when the list is at the top of the stack. It is possible that this is the last entry in the current list but
|
||||
// it is a path that must be checked for entries. In that case the path entries will end up at the top of the stack so we'll
|
||||
// need to wait to free the list containing the path until the path entries have been processed.
|
||||
if (listInfo->listIdx >= storageLstSize(listInfo->list) && listInfo == *(StorageIteratorInfo **)lstGetLast(this->stack))
|
||||
{
|
||||
objFree(listInfo);
|
||||
lstRemoveLast(this->stack);
|
||||
|
@ -444,6 +444,8 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("path - recurse asc");
|
||||
|
||||
// Create a path with a subpath that will always be last to make sure lists are not freed too early in the iterator
|
||||
storagePathCreateP(storageTest, STRDEF("pg/zzz/yyy"), .mode = 0700);
|
||||
|
||||
TEST_STORAGE_LIST(
|
||||
storageTest, "pg",
|
||||
@ -452,7 +454,9 @@ testRun(void)
|
||||
"link> {d=../file}\n"
|
||||
"path/\n"
|
||||
"path/file {s=8, t=1656434296}\n"
|
||||
"pipe*\n",
|
||||
"pipe*\n"
|
||||
"zzz/\n"
|
||||
"zzz/yyy/\n",
|
||||
.level = storageInfoLevelBasic, .includeDot = true);
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -462,6 +466,8 @@ testRun(void)
|
||||
|
||||
TEST_STORAGE_LIST(
|
||||
storageTest, "pg",
|
||||
"zzz/yyy/\n"
|
||||
"zzz/\n"
|
||||
"pipe*\n"
|
||||
"path/file {s=8, t=1656434296}\n"
|
||||
"path/\n"
|
||||
|
Loading…
x
Reference in New Issue
Block a user