mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-18 04:54:54 +00:00
validation-gen/util: add ParseInt utility for canonical integer parsing
Signed-off-by: Bryce Palmer <bpalmer@redhat.com>
This commit is contained in:
@@ -17,6 +17,9 @@ limitations under the License.
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/gengo/v2/parser/tags"
|
||||
"k8s.io/gengo/v2/types"
|
||||
)
|
||||
@@ -114,3 +117,23 @@ func IsDirectComparable(t *types.Type) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ParseInt strictly parses an int from a string input,
|
||||
// ensuring that when converted back to a string, the resulting
|
||||
// int and the input string have the exact same representation.
|
||||
// This prevents scenarios where an input like `0100` parses
|
||||
// as 100 and would be re-stringed as `100`.
|
||||
func ParseInt(val string) (int, error) {
|
||||
intVal, err := strconv.Atoi(val)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("parsing %q as int: %w", val, err)
|
||||
}
|
||||
|
||||
strVal := strconv.Itoa(intVal)
|
||||
if strVal != val {
|
||||
err := fmt.Errorf("parsed int %d converted to a string value of %q which does not match the input string", intVal, strVal)
|
||||
return 0, fmt.Errorf("parsing %q as int: %w", val, err)
|
||||
}
|
||||
|
||||
return intVal, nil
|
||||
}
|
||||
|
||||
@@ -452,3 +452,55 @@ func TestIsDirectComparable(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseInt(t *testing.T) {
|
||||
type testcase struct {
|
||||
name string
|
||||
in string
|
||||
expectedOut int
|
||||
expectedError bool
|
||||
}
|
||||
|
||||
testcases := []testcase{
|
||||
{
|
||||
name: "valid canonical integer string",
|
||||
in: "100",
|
||||
expectedOut: 100,
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "invalid canonical integer string, not an integer at all",
|
||||
in: "notanint",
|
||||
expectedOut: 0,
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "invalid canonical integer string, spurious leading zeros",
|
||||
in: "00100",
|
||||
expectedOut: 0,
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "invalid canonical integer string, octal value",
|
||||
in: "0o123",
|
||||
expectedOut: 0,
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
out, err := ParseInt(tc.in)
|
||||
switch {
|
||||
case tc.expectedError && err == nil:
|
||||
t.Error("expected an error but did not receive one")
|
||||
case !tc.expectedError && err != nil:
|
||||
t.Errorf("received an unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if out != tc.expectedOut {
|
||||
t.Errorf("expected an output value of %d but got %d", tc.expectedOut, out)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user