Skip to content

fix(conv): correct bounds check in ToInt to resolve CodeQL integer-conversion alert - #166

Merged
adityathebe merged 1 commit into
mainfrom
claude/codeql-security-fixes-f6rkti
Jul 17, 2026
Merged

fix(conv): correct bounds check in ToInt to resolve CodeQL integer-conversion alert#166
adityathebe merged 1 commit into
mainfrom
claude/codeql-security-fixes-f6rkti

Conversation

@adityathebe

@adityathebe adityathebe commented Jul 17, 2026

Copy link
Copy Markdown
Member

Summary

Fixes the single open CodeQL code-scanning alert on main:

  • go/incorrect-integer-conversion (CWE-681) — conv/conv.go:225 (ToInt)

The problem

ToInt guarded its int64 → int conversion with a tautology:

if i := ToInt64(in); i <= math.MaxInt || i >= math.MinInt {
    return int(i)
}

Every int64 value satisfies at least one side of that ||, so the condition is always true and int(i) was executed with no effective range check. The tainted value flows from strconv.ParseInt (strToInt64) → ToInt64ToInt, which is exactly the path CodeQL flags. On a 32-bit platform an out-of-range value would be silently truncated instead of returning the intended -1 sentinel described by the comment just below.

The fix

if i := ToInt64(in); i >= math.MinInt && i <= math.MaxInt {
    return int(i)
}

Using && verifies the value lies within [math.MinInt, math.MaxInt] before converting.

  • On 64-bit platforms (MinInt == MinInt64, MaxInt == MaxInt64) behaviour is unchanged.
  • On 32-bit platforms out-of-range values now correctly fall through to return -1.

Verification

Because GitHub scans this repo with the default CodeQL query suite (the workflow specifies no custom queries), I reproduced the alert locally with the matching CodeQL bundle (v2.26.1) and the go-code-scanning.qls suite:

  • Before: 1 alert — go/incorrect-integer-conversion at conv/conv.go:226.
  • After: 0 alerts (full default suite re-run against a freshly rebuilt database).
  • go test ./conv/... passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LRikukPomDzH3VYribFNPU


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Corrected integer conversion boundary validation.
    • Values outside the supported integer range are now rejected consistently instead of being converted incorrectly.

…nversion

The guard in ToInt used `||`, making the condition always true (any int64
is either <= math.MaxInt or >= math.MinInt), so `int(i)` was performed
without an effective range check. On a 32-bit platform this allows a value
outside the int range to be truncated instead of returning the intended
sentinel.

Use `&&` so the value is verified to lie within [math.MinInt, math.MaxInt]
before the conversion. On 64-bit platforms behaviour is unchanged; on
32-bit platforms out-of-range values now correctly return -1.

Fixes the CodeQL go/incorrect-integer-conversion (CWE-681) alert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LRikukPomDzH3VYribFNPU
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

Benchstat

Base: 4559f6acaf9e26e339d75971fe1e0ba508a4c700
Head: 1032e07f9d6ff83df0faaf259c1073f728a99d68

4 minor regression(s) (all within 5% threshold)

Benchmark Base Head Change p-value
RunExpressionContext/cacheHit/smallEnv-4 1.791µ 1.840µ +2.76% 0.017
Serialize_NoNativeTypes/Size-1000-4 913.9µ 932.3µ +2.02% 0.002
Serialize_NoNativeTypes/Size-10000-4 9.136m 9.232m +1.05% 0.002
Serialize/Size-1000-4 3.464m 3.480m +0.46% 0.041
1 improvement(s)
Benchmark Base Head Change p-value
RunExpressionContext/cacheHit/largeEnv-4 10.82µ 10.75µ -0.71% 0.002
Full benchstat output
goos: linux
goarch: amd64
pkg: github.com/flanksource/gomplate/v3
cpu: AMD EPYC 7763 64-Core Processor                
                                               │ bench-base.txt │           bench-head.txt           │
                                               │     sec/op     │    sec/op     vs base              │
RunExpressionContext/cacheHit/smallEnv-4            1.791µ ± 1%   1.840µ ± 19%  +2.76% (p=0.017 n=6)
RunExpressionContext/cacheHit/largeEnv-4            10.82µ ± 7%   10.75µ ±  0%  -0.71% (p=0.002 n=6)
RunExpressionContextCompile/compile/smallEnv-4      348.5µ ± 2%   346.1µ ±  2%       ~ (p=0.093 n=6)
RunExpressionContextCompile/compile/largeEnv-4      357.4µ ± 1%   357.0µ ±  0%       ~ (p=0.132 n=6)
Serialize/Size-10-4                                 36.36µ ± 1%   36.29µ ±  1%       ~ (p=0.589 n=6)
Serialize/Size-100-4                                347.3µ ± 1%   348.6µ ±  1%       ~ (p=0.240 n=6)
Serialize/Size-1000-4                               3.464m ± 0%   3.480m ±  0%  +0.46% (p=0.041 n=6)
Serialize/Size-10000-4                              36.94m ± 2%   37.15m ±  1%       ~ (p=0.310 n=6)
Serialize_NoNativeTypes/Size-100-4                  90.55µ ± 1%   91.40µ ±  2%       ~ (p=0.310 n=6)
Serialize_NoNativeTypes/Size-1000-4                 913.9µ ± 1%   932.3µ ±  2%  +2.02% (p=0.002 n=6)
Serialize_NoNativeTypes/Size-10000-4                9.136m ± 0%   9.232m ±  0%  +1.05% (p=0.002 n=6)
geomean                                             314.2µ        316.1µ        +0.58%

                                               │ bench-base.txt │            bench-head.txt            │
                                               │      B/op      │     B/op      vs base                │
RunExpressionContext/cacheHit/smallEnv-4             664.0 ± 0%     664.0 ± 0%       ~ (p=1.000 n=6) ¹
RunExpressionContext/cacheHit/largeEnv-4           2.445Ki ± 0%   2.445Ki ± 0%       ~ (p=1.000 n=6) ¹
RunExpressionContextCompile/compile/smallEnv-4     194.4Ki ± 0%   194.4Ki ± 0%       ~ (p=0.818 n=6)
RunExpressionContextCompile/compile/largeEnv-4     196.3Ki ± 0%   196.3Ki ± 0%       ~ (p=0.394 n=6)
Serialize/Size-10-4                                11.06Ki ± 0%   11.06Ki ± 0%       ~ (p=1.000 n=6) ¹
Serialize/Size-100-4                               95.52Ki ± 0%   95.52Ki ± 0%       ~ (p=0.833 n=6)
Serialize/Size-1000-4                              952.6Ki ± 0%   952.6Ki ± 0%       ~ (p=0.195 n=6)
Serialize/Size-10000-4                             10.04Mi ± 0%   10.04Mi ± 0%       ~ (p=0.580 n=6)
Serialize_NoNativeTypes/Size-100-4                 36.33Ki ± 0%   36.33Ki ± 0%       ~ (p=1.000 n=6)
Serialize_NoNativeTypes/Size-1000-4                365.6Ki ± 0%   365.6Ki ± 0%       ~ (p=1.000 n=6)
Serialize_NoNativeTypes/Size-10000-4               3.584Mi ± 0%   3.584Mi ± 0%  -0.00% (p=0.002 n=6)
geomean                                            110.7Ki        110.7Ki       -0.00%
¹ all samples are equal

                                               │ bench-base.txt │           bench-head.txt            │
                                               │   allocs/op    │  allocs/op   vs base                │
RunExpressionContext/cacheHit/smallEnv-4             20.00 ± 0%    20.00 ± 0%       ~ (p=1.000 n=6) ¹
RunExpressionContext/cacheHit/largeEnv-4             101.0 ± 0%    101.0 ± 0%       ~ (p=1.000 n=6) ¹
RunExpressionContextCompile/compile/smallEnv-4      2.254k ± 0%   2.254k ± 0%       ~ (p=1.000 n=6) ¹
RunExpressionContextCompile/compile/largeEnv-4      2.337k ± 0%   2.337k ± 0%       ~ (p=1.000 n=6) ¹
Serialize/Size-10-4                                  268.0 ± 0%    268.0 ± 0%       ~ (p=1.000 n=6) ¹
Serialize/Size-100-4                                2.518k ± 0%   2.518k ± 0%       ~ (p=1.000 n=6) ¹
Serialize/Size-1000-4                               25.80k ± 0%   25.80k ± 0%       ~ (p=1.000 n=6)
Serialize/Size-10000-4                              265.0k ± 0%   265.0k ± 0%       ~ (p=0.636 n=6)
Serialize_NoNativeTypes/Size-100-4                   911.0 ± 0%    911.0 ± 0%       ~ (p=1.000 n=6) ¹
Serialize_NoNativeTypes/Size-1000-4                 9.758k ± 0%   9.758k ± 0%       ~ (p=1.000 n=6) ¹
Serialize_NoNativeTypes/Size-10000-4                100.1k ± 0%   100.1k ± 0%  +0.00% (p=0.002 n=6)
geomean                                             2.641k        2.641k       +0.00%
¹ all samples are equal

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Changes

Integer conversion

Layer / File(s) Summary
Correct ToInt bounds validation
conv/conv.go
ToInt now uses an inclusive math.MinIntmath.MaxInt check before converting from int64 to int; out-of-range values return -1.

Suggested reviewers: hairyhenderson

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main fix: correcting ToInt bounds checking to address the CodeQL integer-conversion alert.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/codeql-security-fixes-f6rkti
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/codeql-security-fixes-f6rkti

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@adityathebe
adityathebe merged commit 808f419 into main Jul 17, 2026
8 of 9 checks passed
@adityathebe
adityathebe deleted the claude/codeql-security-fixes-f6rkti branch July 17, 2026 05:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
conv/conv.go (1)

225-226: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a 32-bit regression test for this branch.

The current conv/conv_test.go coverage does not exercise values just outside the 32-bit range. Add architecture-aware tests for math.MaxInt32+1 and math.MinInt32-1, and run them with GOARCH=386 go test ./conv/...; otherwise the corrected condition is not directly protected by the test suite.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@conv/conv.go` around lines 225 - 226, Add architecture-aware regression
coverage in conv/conv_test.go for ToInt64 conversion values just beyond the
32-bit boundaries, specifically math.MaxInt32+1 and math.MinInt32-1, asserting
the expected behavior on 32-bit builds. Run the tests with GOARCH=386 go test
./conv/... to verify the branch guarded by the int-range condition.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@conv/conv.go`:
- Around line 225-226: Update ToInt to handle uint64 inputs without first
converting them to int64; validate the original unsigned value against the int
range before narrowing, and return -1 for values outside that range. Preserve
the existing conversion behavior for values that safely fit in int.

---

Nitpick comments:
In `@conv/conv.go`:
- Around line 225-226: Add architecture-aware regression coverage in
conv/conv_test.go for ToInt64 conversion values just beyond the 32-bit
boundaries, specifically math.MaxInt32+1 and math.MinInt32-1, asserting the
expected behavior on 32-bit builds. Run the tests with GOARCH=386 go test
./conv/... to verify the branch guarded by the int-range condition.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7e7abffb-09c0-49b9-8b36-c4c0e0697e7a

📥 Commits

Reviewing files that changed from the base of the PR and between 4559f6a and 1032e07.

📒 Files selected for processing (1)
  • conv/conv.go

Comment thread conv/conv.go
Comment on lines +225 to 226
if i := ToInt64(in); i >= math.MinInt && i <= math.MaxInt {
return int(i)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== conv/conv.go excerpt ==\n'
sed -n '1,320p' conv/conv.go | nl -ba | sed -n '200,250p'

printf '\n== conv/conv_test.go excerpt ==\n'
sed -n '1,260p' conv/conv_test.go | nl -ba | sed -n '1,260p'

printf '\n== search for ToInt64 and ToInt usage ==\n'
rg -n "func ToInt64|func ToInt|ToInt64\\(|ToInt\\(" conv

Repository: flanksource/gomplate

Length of output: 226


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== conv/conv.go around ToInt/ToInt64 ==\n'
sed -n '200,260p' conv/conv.go | cat -n

printf '\n== conv/conv_test.go relevant excerpts ==\n'
sed -n '1,260p' conv/conv_test.go | cat -n

printf '\n== direct definitions/search ==\n'
rg -n "func ToInt64|func ToInt|ToInt64\\(|ToInt\\(" conv

Repository: flanksource/gomplate

Length of output: 13698


Preserve uint64 values until after the int range check
Large uint64s can wrap to small negative int64s here (for example math.MaxUint64-1 becomes -2), so ToInt returns a bogus int instead of -1. Check the unsigned range before narrowing or keep the value as uint64 through validation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@conv/conv.go` around lines 225 - 226, Update ToInt to handle uint64 inputs
without first converting them to int64; validate the original unsigned value
against the int range before narrowing, and return -1 for values outside that
range. Preserve the existing conversion behavior for values that safely fit in
int.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants