Skip to content

Commit

Permalink
Fix convert processor conversion of string to integer
Browse files Browse the repository at this point in the history
The conversion failed when for strings with leading zeroes and a decimal
digit 8 or 9, as the underlying runtime function would try to parse that
as an octal number.

This is fixed by only allowing decimal and hex, which in turns makes the
processor more aligned to its Elasticsearch counterpart.

Fixes #15513
  • Loading branch information
adriansr committed Jan 14, 2020
1 parent c3a3604 commit de47173
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Fix bug with potential concurrent reads and writes from event.Meta map by Kafka output. {issue}14542[14542] {pull}14568[14568]
- Fix spooling to disk blocking infinitely if the lock file can not be acquired. {pull}15338[15338]
- Fix `metricbeat test output` with an ipv6 ES host in the output.hosts. {pull}15368[15368]
- Fix `convert` processor conversion of string to integer with leading zeros. {issue}15513[15513]

*Auditbeat*

Expand Down
14 changes: 12 additions & 2 deletions libbeat/processors/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func toString(value interface{}) (string, error) {
func toLong(value interface{}) (int64, error) {
switch v := value.(type) {
case string:
return strconv.ParseInt(v, 0, 64)
return strToInt(v, 64)
case int:
return int64(v), nil
case int8:
Expand Down Expand Up @@ -238,7 +238,7 @@ func toLong(value interface{}) (int64, error) {
func toInteger(value interface{}) (int32, error) {
switch v := value.(type) {
case string:
i, err := strconv.ParseInt(v, 0, 32)
i, err := strToInt(v, 32)
return int32(i), err
case int:
return int32(v), nil
Expand Down Expand Up @@ -403,3 +403,13 @@ func cloneValue(value interface{}) interface{} {
return value
}
}

// Helper to interpret a string as either base-10 or base-16.
func strToInt(v string, bitSize int) (int64, error) {
base := 10
if strings.IndexAny(v, "xX") != -1 {
// strconv.ParseInt only accepts the '0x' prefix when base is 0.
base = 0
}
return strconv.ParseInt(v, base, bitSize)
}
19 changes: 19 additions & 0 deletions libbeat/processors/convert/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,16 @@ var testCases = []testCase{

{Long, nil, nil, true},
{Long, "x", nil, true},
{Long, "0x", nil, true},
{Long, "0b1", nil, true},
{Long, "1x2", nil, true},
{Long, true, nil, true},
{Long, "1", int64(1), false},
{Long, "-1", int64(-1), false},
{Long, "017", int64(17), false},
{Long, "08", int64(8), false},
{Long, "0X0A", int64(10), false},
{Long, "-0x12", int64(-18), false},
{Long, int(1), int64(1), false},
{Long, int8(1), int64(1), false},
{Long, int16(1), int64(1), false},
Expand All @@ -294,6 +302,17 @@ var testCases = []testCase{
{Integer, nil, nil, true},
{Integer, "x", nil, true},
{Integer, true, nil, true},
{Integer, "x", nil, true},
{Integer, "0x", nil, true},
{Integer, "0b1", nil, true},
{Integer, "1x2", nil, true},
{Integer, true, nil, true},
{Integer, "1", int32(1), false},
{Integer, "-1", int32(-1), false},
{Integer, "017", int32(7), false},
{Integer, "08", int32(8), false},
{Integer, "0X0A", int32(10), false},
{Integer, "-0x12", int32(-18), false},
{Integer, "1", int32(1), false},
{Integer, int(1), int32(1), false},
{Integer, int8(1), int32(1), false},
Expand Down

0 comments on commit de47173

Please sign in to comment.