fix(sql): validate unsigned int not-null fields without panicking#3677
fix(sql): validate unsigned int not-null fields without panicking#3677umarahad2005 wants to merge 3 commits into
Conversation
validateNotNull routes uint/uint8/uint16/uint32/uint64 values into
validateIntNotNull, which calls reflect.Value.Int(). That method panics
on unsigned kinds ("reflect: call of reflect.Value.Int on uint Value"),
so any not_null field of an unsigned type crashed InsertQuery - and with
it the auto-generated CRUD create handler - on every request.
Add validateUintNotNull using reflect.Value.Uint() and route the unsigned
kinds to it, mirroring the existing validateFloatNotNull helper.
Add a focused unit test plus an InsertQuery case covering the unsigned
not-null path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Fixes a panic in GoFr’s SQL not_null validation when inserting entities containing unsigned integer fields, ensuring CRUD create handlers validate unsigned fields correctly instead of crashing.
Changes:
- Split unsigned integer handling out of the signed-int path in
validateNotNullto avoidreflect.Value.Int()panics. - Added
validateUintNotNullusingreflect.Value.Uint()foruint*kinds. - Added unit tests covering the unsigned-int validation and an InsertQuery not-null error scenario.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pkg/gofr/datasource/sql/query_builder.go | Routes unsigned integer types to a new uint-specific not-null validator to prevent reflect panics. |
| pkg/gofr/datasource/sql/query_builder_test.go | Adds coverage ensuring unsigned-int not-null validation errors instead of panicking. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| require.NoError(t, validateNotNull("views", uint(5), true)) | ||
| require.NoError(t, validateNotNull("views", uint64(9), true)) | ||
| require.EqualError(t, validateNotNull("views", uint(0), true), "field cannot be zero: views") |
Umang01-hash
left a comment
There was a problem hiding this comment.
Fix is correct and well-tested. One request before merge: the same panic class you're fixing still exists on the default path — worth closing it in the same PR while you're here. Details inline.
| return validateUintNotNull(fieldName, v) | ||
| case float32, float64: | ||
| return validateFloatNotNull(fieldName, v) | ||
| default: |
There was a problem hiding this comment.
Same bug class as the uint fix: this default branch routes to validateDefaultNotNull, which calls reflect.Value.IsNil() — that panics on non-nillable kinds. A NotNull bool, time.Time, or uintptr field will panic here (verified). Since you're already fixing the unsigned case, please guard this path too (check Kind() before IsNil(), or handle bool/time explicitly) and add a test.
Addresses review on gofr-dev#3677. The default branch of validateNotNull calls reflect.Value.IsNil(), which panics on non-nillable kinds - the same panic class as the unsigned-int fix. A NOT NULL field of type bool, a struct such as time.Time, uintptr, array, etc. crashed InsertQuery (and the auto CRUD create handler). Only call IsNil() for kinds where it is defined (via isNillableKind), and treat an untyped-nil interface (reflect.Invalid) as null. Non-nillable kinds can never be null and are now accepted. Also expand the unsigned test to exercise every uint width (uint8/16/32) so none can regress to the default path, and add a test covering the non-nillable kinds and the nil cases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the review, @Umang01-hash — good catch.
Test coverage (@copilot): the unsigned test now exercises every uint width — Ready for another look. |
Description:
validateNotNull(pkg/gofr/datasource/sql/query_builder.go) routesuint, uint8, uint16, uint32, uint64values intovalidateIntNotNull, which callsreflect.Value.Int(). That method panics on unsigned kinds:validateNotNullis called fromInsertQuery, which powers GoFr's auto-generated CRUD create handler (crud_handlers.go). So an entity with an unsignednot_nullfield, for example:panics the request handler on every create — for any value, not just zero.
Fix: add
validateUintNotNullusingreflect.Value.Uint()and route the unsigned kinds to it, mirroring the existingvalidateFloatNotNullhelper. The signed-integer path is unchanged.No tracking issue exists for this; it was found while reading the not-null validation.
Breaking Changes (if applicable):
None. These values previously panicked; they now validate correctly (zero →
field cannot be zero, non-zero → ok), consistent with the signed and float paths.Additional Information:
go test: the added unsigned-int cases panic on the current code and pass after the fix.Checklist:
goimportandgolangci-lint.