Skip to content

Commit 6c55698

Browse files
Youen Pérongiraud10adrienaury
authored
fix: use fromcache after a mask which causes a change in the type of the value (#110)
* test: add bug in venom test * fix(fromCache): bad number type in cache * fix: regression on dataParser mask * test: fix test clean type * test: fix template notation * test: fix venom test * docs: update changelog Co-authored-by: Marie Giraud <marie.giraud@cgi.com> Co-authored-by: adrienaury <adrien.aury@cgi.com>
1 parent 76cca70 commit 6c55698

File tree

11 files changed

+134
-12
lines changed

11 files changed

+134
-12
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Types of changes
1414
- `Fixed` for any bug fixes.
1515
- `Security` in case of vulnerabilities.
1616

17+
## [1.12.1]
18+
19+
- `Fixed` use fromcache after a mask which causes a change in the type of the value
20+
1721
## [1.12.0]
1822

1923
- `Added` markov mask to generate pseudo text based on a sample text

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ require (
1111
github.com/labstack/echo/v4 v4.7.2
1212
github.com/mattn/go-isatty v0.0.14
1313
github.com/rs/zerolog v1.26.1
14+
github.com/spf13/cast v1.4.1
1415
github.com/spf13/cobra v1.4.0
1516
github.com/stretchr/testify v1.7.1
1617
github.com/zach-klippenstein/goregen v0.0.0-20160303162051-795b5e3961ea
@@ -37,7 +38,6 @@ require (
3738
github.com/pmezard/go-difflib v1.0.0 // indirect
3839
github.com/shopspring/decimal v1.2.0 // indirect
3940
github.com/smartystreets/goconvey v1.6.4 // indirect
40-
github.com/spf13/cast v1.4.1 // indirect
4141
github.com/spf13/pflag v1.0.5 // indirect
4242
github.com/valyala/bytebufferpool v1.0.0 // indirect
4343
github.com/valyala/fasttemplate v1.2.1 // indirect

pkg/constant/constant.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type MaskEngine struct {
2929

3030
// NewMask return a MaskEngine from a value
3131
func NewMask(data model.Entry) MaskEngine {
32-
return MaskEngine{data}
32+
return MaskEngine{model.CleanTypes(data)}
3333
}
3434

3535
// Mask return a Constant from a MaskEngine

pkg/dateparser/dateparser.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
package dateparser
1919

2020
import (
21-
"encoding/json"
2221
"fmt"
2322
"time"
2423

2524
"github.com/cgi-fr/pimo/pkg/model"
2625
"github.com/rs/zerolog/log"
26+
"github.com/spf13/cast"
2727
)
2828

2929
// MaskEngine is a type to change a date format
@@ -47,7 +47,7 @@ func (me MaskEngine) Mask(e model.Entry, context ...model.Dictionary) (model.Ent
4747
var err error
4848
switch {
4949
case me.inputFormat == "unixEpoch":
50-
i, err := e.(json.Number).Int64()
50+
i, err := cast.ToInt64E(e)
5151
if err != nil {
5252
return nil, err
5353
}

pkg/dateparser/dateparser_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func TestFactoryShouldCreateAMask(t *testing.T) {
9696
func TestMaskingShouldReplaceUnixEpochByDateString(t *testing.T) {
9797
outputFormat := "02/01/06"
9898
dateMask := NewMask("unixEpoch", outputFormat)
99-
data := json.Number("1647512434")
99+
data := model.CleanTypes(json.Number("1647512434"))
100100
resulttime, err := dateMask.Mask(data)
101101
assert.Equal(t, nil, err, "error should be nil")
102102
assert.Equal(t, "17/03/22", resulttime, "Should return the same time")

pkg/model/model.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ func (sink *SinkToCache) Open() error {
422422
}
423423

424424
func (sink *SinkToCache) ProcessDictionary(dictionary Dictionary) error {
425-
sink.cache.Put(dictionary.Get("key"), dictionary.Get("value"))
425+
sink.cache.Put(CleanTypes(dictionary.Get("key")), CleanTypes(dictionary.Get("value")))
426426
return nil
427427
}
428428

pkg/model/ordered_dict.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package model
22

33
import (
4+
"encoding/json"
45
"fmt"
56

67
"github.com/rs/zerolog/log"
@@ -91,6 +92,23 @@ func CleanTypes(inter interface{}) interface{} {
9192
}
9293

9394
return tab
95+
96+
case json.Number:
97+
98+
resFloat64, err := typedInter.Float64()
99+
if err == nil {
100+
return resFloat64
101+
}
102+
103+
return typedInter.String()
104+
105+
case uint64:
106+
res := float64(typedInter)
107+
return res
108+
109+
case int64:
110+
res := float64(typedInter)
111+
return res
94112
default:
95113
return inter
96114
}

pkg/rangemask/rangemask.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
package rangemask
1919

2020
import (
21-
"encoding/json"
21+
"fmt"
2222
"strconv"
2323

2424
"github.com/cgi-fr/pimo/pkg/model"
@@ -41,9 +41,10 @@ func (rm MaskEngine) Mask(e model.Entry, context ...model.Dictionary) (model.Ent
4141
if e == nil {
4242
return e, nil
4343
}
44-
i, err := e.(json.Number).Int64()
45-
if err != nil {
46-
return nil, err
44+
i, ok := e.(float64)
45+
46+
if !ok {
47+
return e, fmt.Errorf("%v is not a number", e)
4748
}
4849
scaledValue := int(i) / rm.rangeScale * rm.rangeScale
4950
rangedValue := "[" + strconv.Itoa(scaledValue) + ";" + strconv.Itoa(scaledValue+rm.rangeScale-1) + "]"

pkg/rangemask/rangemask_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package rangemask
1919

2020
import (
2121
"encoding/json"
22+
"fmt"
2223
"testing"
2324

2425
"github.com/cgi-fr/pimo/pkg/model"
@@ -27,13 +28,19 @@ import (
2728

2829
func TestMaskingShouldReplaceSensitiveValueByRangedValue(t *testing.T) {
2930
rangeMask := NewMask(10)
30-
result, err := rangeMask.Mask(json.Number("25"))
31+
result, err := rangeMask.Mask(model.CleanTypes(json.Number("25")))
3132
assert.Equal(t, nil, err, "error should be nil")
3233
waited := "[20;29]"
3334
assert.NotEqual(t, float64(25), result, "should be masked")
3435
assert.Equal(t, waited, result, "should be [20;29]")
3536
}
3637

38+
func TestMaskingShouldFailwithNotNumberInput(t *testing.T) {
39+
rangeMask := NewMask(10)
40+
_, err := rangeMask.Mask("not a number")
41+
assert.Equal(t, fmt.Errorf("not a number is not a number"), err, "error should not be nil")
42+
}
43+
3744
func TestFactoryShouldCreateAMask(t *testing.T) {
3845
maskingConfig := model.Masking{Mask: model.MaskType{RangeMask: 15}}
3946
mask, present, err := Factory(maskingConfig, 0, nil)

test/suites/masking_cache.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,3 +515,71 @@ testcases:
515515
- result.systemout ShouldContainSubstring {"key":"Mathieu","value":"FDDO8965"}
516516
- result.systemout ShouldContainSubstring {"key":"Marcel","value":"FTTO4452"}
517517
- result.systemout ShouldContainSubstring {"key":"Mickael","value":"FJUS4442"}
518+
519+
- name: bug fromCache with calculated value 1
520+
steps:
521+
- script: rm -f masking.yml
522+
- script: |-
523+
cat > masking.yml <<EOF
524+
version: "1"
525+
seed: 42
526+
masking:
527+
- selector:
528+
jsonpath: "sexe"
529+
masks:
530+
- constant: 2
531+
- fromCache: "cacheSex"
532+
533+
caches:
534+
cacheSex :
535+
unique: true
536+
reverse: true
537+
EOF
538+
- script: |-
539+
cat > cacheSex.jsonl <<EOF
540+
{"key": "M", "value": 2}
541+
{"key": "F", "value": 1}
542+
EOF
543+
- script: |-
544+
pimo --load-cache cacheSex=./cacheSex.jsonl <<EOF
545+
{"sexe": 2.4}
546+
EOF
547+
assertions:
548+
- result.code ShouldEqual 0
549+
- result.systemout ShouldContainSubstring '{"sexe":"M"}'
550+
- result.systemerr ShouldBeEmpty
551+
552+
- name: bug fromCache with calculated value 2
553+
steps:
554+
- script: rm -f masking.yml
555+
- script: |-
556+
cat > masking.yml <<EOF
557+
version: "1"
558+
seed: 42
559+
masking:
560+
- selector:
561+
jsonpath: "sexe"
562+
masks:
563+
- template : '[[ round (toString .sexe) 0 ]]'
564+
- fromjson: "sexe"
565+
- fromCache: "cacheSex"
566+
caches:
567+
cacheSex :
568+
unique: true
569+
reverse: true
570+
EOF
571+
- script: sed -i "s/\[\[/\{\{/g" masking.yml
572+
- script: sed -i "s/\]\]/\}\}/g" masking.yml
573+
- script: |-
574+
cat > cacheSex.jsonl <<EOF
575+
{"key": "M", "value": 2}
576+
{"key": "F", "value": 1}
577+
EOF
578+
- script: |-
579+
pimo --load-cache cacheSex=./cacheSex.jsonl <<EOF
580+
{"sexe": 2.4}
581+
EOF
582+
assertions:
583+
- result.code ShouldEqual 0
584+
- result.systemout ShouldContainSubstring '{"sexe":"M"}'
585+
- result.systemerr ShouldBeEmpty

0 commit comments

Comments
 (0)