-
Notifications
You must be signed in to change notification settings - Fork 721
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 nil input to starting key of batch lookup #1189
Fix nil input to starting key of batch lookup #1189
Conversation
Batch lookup requires the caller to provide the starting key (`startKey`) from which the lookup begins. In order to perform a batch lookup from the very beginning of the map, it is expected to pass a nil `startKey`. Due to the type of `startKey` being `interface{}`, this means that it's possible for the value of `startKey` to have a concrete type T, but contain a nil value. For example, let's say the concrete type T is an *int. ``` func dumpAll[T comparable](m *Map, startKey, key *T) (count int, err error) { ... m.batchLookup(..., startKey, ...) ... } dumpAll(m, nil, new(int)) ``` The first call to `dumpAll()` must pass nil to `startKey`. When it reaches `(*Map).batchLookup()`, `startKey` becomes a _non-nil_ `interface{}` with an underlying concrete type of `*int`, whose value _is_ nil. This is problematic because `startKey != nil` evaluates to true and the call to `marshalMapSyscallInput()` expects `startKey` to contain a non-nil value. This commit fixes this by checking whether the underlying value of the interface contains a non-nil value. Signed-off-by: Chris Tarazi <[email protected]>
Hmm, what about Could you work around this issue in your generic function by defining |
I'm happy to expand this PR to be consist everywhere else.
The problem with this suggestion is that it riddles the code with
By doing this though, it allows users to use both Supporting generics at the cost of one extra function call to reflect.ValueOf doesn't seem to be too consequential. |
I don't fully understand how this prevents using generics. I guess you mean "makes calling the API from generic code cumbersome"? From your description it sounds like there is an error returned by the method, but its probably cryptic? Maybe you have a link to the code you want to be able to write?
The cost isn't in the overhead of reflect.ValueOf but in auditing the code to find all the places it is needed and maintaining these semantics in the future. My biggest worry is that for consistency we'd need to handle nil vs typed nil for more |
@lmb The example code I'm writing is cilium/cilium#28183. See function |
JFYI, I've managed to workaround this issue by having the |
Nice! For what it's worth, this change might still be worth it, provided we only have to do this check for NextKey and Batch lookups. @ti-mo any opinions on whether we should tackle nil vs interface nil? What else would we have to take into account? You also mentioned that prevKey isn't really a key but more of an opaque handle of sorts? Does it make sense to rename the parameter or document this behaviour? |
Yes, I will file a PR that documents the behavior and consider a rename this week. |
Superseded by #1223 |
Batch lookup requires the caller to provide the starting key
(
startKey
) from which the lookup begins. In order to perform a batchlookup from the very beginning of the map, it is expected to pass a nil
startKey
. Due to the type ofstartKey
beinginterface{}
, thismeans that it's possible for the value of
startKey
to have a concretetype T, but contain a nil value.
For example, let's say the concrete type T is an *int.
The first call to
dumpAll()
must pass nil tostartKey
. When itreaches
(*Map).batchLookup()
,startKey
becomes a non-nilinterface{}
with an underlying concrete type of*int
, whose valueis nil.
This is problematic because
startKey != nil
evaluates to true and thecall to
marshalMapSyscallInput()
expectsstartKey
to contain anon-nil value.
This commit fixes this by checking whether the underlying value of the
interface contains a non-nil value.
Signed-off-by: Chris Tarazi [email protected]