Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix another hosts.Remove() issue #48

Merged
merged 9 commits into from
Dec 20, 2023
Merged

Conversation

cfergeau
Copy link
Contributor

This PR reworks the hosts.Remove() fix which was done in 0.5.1 to make it more
efficient, and consistent with a second fix done in this PR.
We have issues with hosts.Remove() both when removing entries from a single
line, but also when the removal of host entries empties some lines and causes
their removal.
0.5.1 fixed the former but not the latter. This PR should fix both, and adds
test cases for the second issue.

This reverts commit e336a9e.

This keeps the added testcase, but the issue will be fixed differently
in one of the following commits.

The current fix is fine, even if it's slightly wasteful as it iterates N
times over the same line to try to remove hosts entries from it.
The main reason for changing it is that this series will fix a second
bug, and this will allow to keep consistency between the way we iterate
over all the lines, and how we iterate over all the hosts in a given
line.
This checks if the host file has the expected content after
removing all entries from it.
TestDeleteSliceBoundErrorOnRemove does not need to create many
crc-specific entries, the bug can be reproduced with just 2 entries
which are deleted in the same call to hosts.Remove().
This commit changes the test to be minimal. It's also renamed to a more
descriptive name.
It is the same as TestRemoveMultipleForwardSameLine except that
it removes the entries in the opposite order that they are listed in the
hosts file.
Removing multiple entries from the same line in one call to
hosts.Remove() can currently result in an out-of-bound access and a
panic.

The removal is done by iterating over the entries, and calling
removeHostFromLine with the index of the entry to remove from the line.
If the line has for example 2 entries, and we want to remove both, we'll
call removeHostFromLine(0) and then removeHostFromLine(1).

However, after the first removal, the line no longer has an entry with
index 1, which causes the out-of-bound access and the panic when we try
to access it.

To avoid this problem, we can loop over the line from the end, even if
we remove entries, the index of the ones we remove afterwards will still
be valid as they are before the ones we removed.
If hosts.Remove() is called with multiple arguments, and the removal
triggers the deletion of an empty line, then the removal of subsequent
host entries can cause out of bounds accesses, as we access the line by
index, and we don't reset our indexes after removing the line.

It's a similar issue to the one fixed in "Fix TestRemoveMultiple*SameLine"
except that it occurs when iterating over the lines instead of iterating
over the hosts on a line.

It's fixed in a similar way, by iterating backwards so that even if we
remove a line, this does not invalidate the indexes of the lines we'll
check after the removed line.
For some reason, when deduplicating the hosts passed to hosts.Remove, we
were first generating a map of bool and then generating a map of
struct{}. The 2 maps would have the same set of keys, corresponding
to the list of hosts with no duplicates.

The second map can be generated directly without generating the
uniqueHosts map first.
While the removal code when there is no crc section does not seem to
be impacted by the issues recently fixed, it does not hurt to have a
test for it.
This simplifies hosts_test.go code.
@evidolob evidolob merged commit f26c14e into crc-org:master Dec 20, 2023
1 check passed
@cfergeau cfergeau deleted the remove branch December 21, 2023 10:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants