-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Cast less blindly between configuration objects #4552
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
Conversation
We pass this around and when creating a new iterator we need to read the repository pointer. Put it in a common place so we can reach it regardless of whether we got a full object or a snapshot.
We use it in a few places where we might have a full object or a snapshot so move it to where we can actually access it.
When we create an iterator we don't actually know that we have a live config object and we must instead only rely on the header. We fixed it to use this in a previous commit, but this makes it harder to misuse by converting to use the header object in the typecast. We also guard inside the `config_refresh` function against being given a snapshot (although callers right now do check).
src/config_file.c
Outdated
@@ -326,6 +326,9 @@ static int config_refresh(git_config_backend *cfg) | |||
int error, modified; | |||
uint32_t i; | |||
|
|||
if (b->header.parent.readonly) | |||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm. Not all callers do check that, most notably config_set
and config_delete
functions don't. So this does change behavior, no? This change definitly looks a bit scary to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config_set
and config_delete
only are set as the set and delete functions for the "live"/read-write object so. The snapshots (i.e. when readonly
would be true) sets its own functions which return with an error.
So config_set
and config_delete
would only be called when readonly
is false and thus simply continue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, missed that, thanks for pointing out. The only thought left is that it feels a bit weird to return success even if we bail out early. I'd say returning an error code is a bit cleaner, as that may not leave us wondering at a later point why just some random configs are never being refreshed. As callers don't call refresh
anyway when the config is read-only, this shouldn't have any negative impact right now but feels safer for the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do have a function that we use in case you accidentally end up calling set and friends on a snapshot. I'll make it return that.
Instead of treating it as a no-op, treat it as a programming error and return the same kind of error as if you called to set or delete variables on a snapshot.
As discussed in #4551 we were cowboying it up with the casts which meant we were passing in nonsense values for levels and reading unallocated memory for the repository pointer.
This fixes that and hardens the code a bit by casting to the common structure rather than the one for the live object.
/cc @tiennou
//c @ethomson @pks-t this should go in before the release