Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/app/api/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (a *app) SetupDemo() error {
return errors.New("failed to setup demo")
}

_, err = a.services.Items.CsvImport(ctx, self.DefaultGroupID, strings.NewReader(csvText))
_, err = a.services.Entities.CsvImport(ctx, self.DefaultGroupID, strings.NewReader(csvText))
if err != nil {
log.Err(err).Msg("Failed to import CSV")
return errors.New("failed to setup demo")
Expand Down
3 changes: 1 addition & 2 deletions backend/app/api/handlers/v1/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,7 @@ func (ctrl *V1Controller) HandleCacheWS() errchain.HandlerFunc {
}

ctrl.bus.Subscribe(eventbus.EventTagMutation, factory("tag.mutation"))
ctrl.bus.Subscribe(eventbus.EventLocationMutation, factory("location.mutation"))
ctrl.bus.Subscribe(eventbus.EventItemMutation, factory("item.mutation"))
ctrl.bus.Subscribe(eventbus.EventEntityMutation, factory("entity.mutation"))
ctrl.bus.Subscribe(eventbus.EventUserMutation, factory("user.mutation"))

// Persistent asynchronous ticker that keeps all websocket connections alive with periodic pings.
Expand Down
12 changes: 6 additions & 6 deletions backend/app/api/handlers/v1/v1_ctrl_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func actionHandlerFactory(ref string, fn func(context.Context, uuid.UUID) (int,
// @Router /v1/actions/ensure-asset-ids [Post]
// @Security Bearer
func (ctrl *V1Controller) HandleEnsureAssetID() errchain.HandlerFunc {
return actionHandlerFactory("ensure asset IDs", ctrl.svc.Items.EnsureAssetID)
return actionHandlerFactory("ensure asset IDs", ctrl.svc.Entities.EnsureAssetID)
}

// HandleEnsureImportRefs godoc
Expand All @@ -55,7 +55,7 @@ func (ctrl *V1Controller) HandleEnsureAssetID() errchain.HandlerFunc {
// @Router /v1/actions/ensure-import-refs [Post]
// @Security Bearer
func (ctrl *V1Controller) HandleEnsureImportRefs() errchain.HandlerFunc {
return actionHandlerFactory("ensure import refs", ctrl.svc.Items.EnsureImportRef)
return actionHandlerFactory("ensure import refs", ctrl.svc.Entities.EnsureImportRef)
}

// HandleItemDateZeroOut godoc
Expand All @@ -68,7 +68,7 @@ func (ctrl *V1Controller) HandleEnsureImportRefs() errchain.HandlerFunc {
// @Router /v1/actions/zero-item-time-fields [Post]
// @Security Bearer
func (ctrl *V1Controller) HandleItemDateZeroOut() errchain.HandlerFunc {
return actionHandlerFactory("zero out date time", ctrl.repo.Items.ZeroOutTimeFields)
return actionHandlerFactory("zero out date time", ctrl.repo.Entities.ZeroOutTimeFields)
}

// HandleSetPrimaryPhotos godoc
Expand All @@ -81,7 +81,7 @@ func (ctrl *V1Controller) HandleItemDateZeroOut() errchain.HandlerFunc {
// @Router /v1/actions/set-primary-photos [Post]
// @Security Bearer
func (ctrl *V1Controller) HandleSetPrimaryPhotos() errchain.HandlerFunc {
return actionHandlerFactory("ensure asset IDs", ctrl.repo.Items.SetPrimaryPhotos)
return actionHandlerFactory("ensure asset IDs", ctrl.repo.Entities.SetPrimaryPhotos)
}

// HandleCreateMissingThumbnails godoc
Expand Down Expand Up @@ -138,7 +138,7 @@ func (ctrl *V1Controller) HandleWipeInventory() errchain.HandlerFunc {
}
}

totalCompleted, err := ctrl.repo.Items.WipeInventory(ctx, ctx.GID, options.WipeTags, options.WipeLocations, options.WipeMaintenance)
totalCompleted, err := ctrl.repo.Entities.WipeInventory(ctx, ctx.GID, options.WipeTags, options.WipeLocations, options.WipeMaintenance)
if err != nil {
log.Err(err).Str("action_ref", "wipe inventory").Msg("failed to run action")
return validate.NewRequestError(err, http.StatusInternalServerError)
Expand All @@ -150,7 +150,7 @@ func (ctrl *V1Controller) HandleWipeInventory() errchain.HandlerFunc {
ctrl.bus.Publish(eventbus.EventTagMutation, eventbus.GroupMutationEvent{GID: ctx.GID})
}
if options.WipeLocations {
ctrl.bus.Publish(eventbus.EventLocationMutation, eventbus.GroupMutationEvent{GID: ctx.GID})
ctrl.bus.Publish(eventbus.EventEntityMutation, eventbus.GroupMutationEvent{GID: ctx.GID})
}
}

Expand Down
4 changes: 2 additions & 2 deletions backend/app/api/handlers/v1/v1_ctrl_assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// @Tags Items
// @Produce json
// @Param id path string true "Asset ID"
// @Success 200 {object} repo.PaginationResult[repo.ItemSummary]{}
// @Success 200 {object} repo.PaginationResult[repo.EntitySummary]{}
// @Router /v1/assets/{id} [GET]
// @Security Bearer
func (ctrl *V1Controller) HandleAssetGet() errchain.HandlerFunc {
Expand Down Expand Up @@ -52,7 +52,7 @@
}
}

items, err := ctrl.repo.Items.QueryByAssetID(r.Context(), ctx.GID, repo.AssetID(assetID), int(page), int(pageSize))
items, err := ctrl.repo.Entities.QueryByAssetID(r.Context(), ctx.GID, repo.AssetID(assetID), int(page), int(pageSize))

Check failure

Code scanning / CodeQL

Incorrect conversion between integer types High

Incorrect conversion of a signed 64-bit integer from
strconv.ParseInt
to a lower bit size type int without an upper bound check.

Copilot Autofix

AI about 20 hours ago

General approach: ensure that the bit size used when parsing matches the bit size of the target type, or add explicit upper-/lower-bound checks before converting to a smaller type. Since we cannot change repo.AssetID or see its exact definition, we should parse assetIDParam directly into the same effective bit width that repo.AssetID uses. CodeQL’s complaint is that we parse as 64 bits then cast to something smaller, so the minimal, non-breaking fix is to reduce the parse bit size to match int (32 bits on CodeQL’s model) while leaving business logic intact.

Best specific fix here: change the assetID parsing on line 33 from ParseInt(..., 10, 64) to ParseInt(..., 10, 32) (matching how page and pageSize are parsed) and adjust assetID’s type to int64 or keep it but note that ParseInt with bitSize=32 already enforces 32-bit bounds. That way, any out-of-range value for a 32-bit type results in a parse error instead of silent truncation when converting to repo.AssetID. The rest of the handler logic and signatures remain unchanged.

Concretely:

  • In backend/app/api/handlers/v1/v1_ctrl_assets.go:
    • Update the comment and the call on line 33 to use bit size 32: strconv.ParseInt(assetIDParam, 10, 32).
    • Keep the error handling and the use of repo.AssetID(assetID) as is.
  • No new imports or helper methods are needed.

Suggested changeset 1
backend/app/api/handlers/v1/v1_ctrl_assets.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/backend/app/api/handlers/v1/v1_ctrl_assets.go b/backend/app/api/handlers/v1/v1_ctrl_assets.go
--- a/backend/app/api/handlers/v1/v1_ctrl_assets.go
+++ b/backend/app/api/handlers/v1/v1_ctrl_assets.go
@@ -29,8 +29,8 @@
 		ctx := services.NewContext(r.Context())
 		assetIDParam := chi.URLParam(r, "id")
 		assetIDParam = strings.ReplaceAll(assetIDParam, "-", "") // Remove dashes
-		// Convert the asset ID to an int64
-		assetID, err := strconv.ParseInt(assetIDParam, 10, 64)
+		// Convert the asset ID to an int32-sized value; reject out-of-range values
+		assetID, err := strconv.ParseInt(assetIDParam, 10, 32)
 		if err != nil {
 			return err
 		}
EOF
@@ -29,8 +29,8 @@
ctx := services.NewContext(r.Context())
assetIDParam := chi.URLParam(r, "id")
assetIDParam = strings.ReplaceAll(assetIDParam, "-", "") // Remove dashes
// Convert the asset ID to an int64
assetID, err := strconv.ParseInt(assetIDParam, 10, 64)
// Convert the asset ID to an int32-sized value; reject out-of-range values
assetID, err := strconv.ParseInt(assetIDParam, 10, 32)
if err != nil {
return err
}
Copilot is powered by AI and may make mistakes. Always verify output.
if err != nil {
log.Err(err).Msg("failed to get item")
return validate.NewRequestError(err, http.StatusInternalServerError)
Expand Down
Loading
Loading