diff --git a/README.md b/README.md index e629bfb..6432087 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,13 @@ var myInt int f.Fuzz(&myInt) // myInt gets a random value. ``` -You can use it on string with different character, like ASCII, MultiByte, -CommonCJK, Chinese, Japanese, Number, Lower-Case, Upper-Case or -Random(each rune will be one of the above character). +If you want to use it on string with different character like Chinese or Number, +you can get Unicode range from [Unicode](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane), +and parse the low and high encoding into function `WithCharRange`. For example Chinese: ```go f := fuzz.New() var myString string -f.WithStringGenMode(fuzz.Chinese).Fuzz(&myString) +f.WithCharRange('\u4e00', '\u9fa5').Fuzz(&myString) ``` You can use it on maps: diff --git a/fuzz.go b/fuzz.go index d724833..207641e 100644 --- a/fuzz.go +++ b/fuzz.go @@ -40,7 +40,7 @@ type Fuzzer struct { maxElements int maxDepth int skipFieldPatterns []*regexp.Regexp - stringGenMode int + characterRange *charRange } // New returns a new Fuzzer. Customize your Fuzzer further by calling Funcs, @@ -61,8 +61,8 @@ func NewWithSeed(seed int64) *Fuzzer { minElements: 1, maxElements: 10, maxDepth: 100, - // random mode as default mode to gen string - stringGenMode: Random, + // characterRange will be nil if you not set the encoding range + characterRange: nil, } return f } @@ -193,11 +193,12 @@ func (f *Fuzzer) SkipFieldsWithPattern(pattern *regexp.Regexp) *Fuzzer { return f } -// WithStringGenMode is used to set the string generation mode. Mode includes ASCII, -// MultiByte, CommonCJK, Chinese, Japanese, Number, Lower case, Upper case or -// random mode(each rune will use one character.). -func (f *Fuzzer) WithStringGenMode(mode int) *Fuzzer { - f.stringGenMode = mode +// WithCharRange is used to set the Unicode encoding range of the string. +func (f *Fuzzer) WithCharRange(first, last rune) *Fuzzer { + f.characterRange = &charRange{ + first: first, + last: last, + } return f } @@ -285,9 +286,9 @@ func (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) { switch v.Kind() { // String is common data struct but handle it with function randString - // randString should input string generation mode. + // randString should input character range although it is nil case reflect.String: - v.SetString(randString(fc.fuzzer.r, fc.fuzzer.stringGenMode)) + v.SetString(randString(fc.fuzzer.r, fc.fuzzer.characterRange)) case reflect.Map: if fc.fuzzer.genShouldFill() { @@ -445,13 +446,7 @@ func (c Continue) FuzzNoCustom(obj interface{}) { // RandString makes a random string up to 20 characters long. The returned string // may include a variety of (valid) UTF-8 encodings. func (c Continue) RandString() string { - return randString(c.Rand, c.fc.fuzzer.stringGenMode) -} - -// RandChineseString makes a random string up to 20 characters long. The returned string -// may include a variety of (valid) UTF-8 encodings. Rand unicode: \u4e00 - \u9fa5 -func (c Continue) RandChinesesString() string { - return randChineseString(c.Rand) + return randString(c.Rand, c.fc.fuzzer.characterRange) } // RandUint64 makes random 64 bit numbers. @@ -538,49 +533,20 @@ var unicodeRanges = []charRange{ {' ', '~'}, // ASCII characters {'\u00a0', '\u02af'}, // Multi-byte encoded characters {'\u4e00', '\u9fff'}, // Common CJK (even longer encodings) - {'\u4e00', '\u9fa5'}, // Chinese - {'\u0800', '\u4e00'}, // Japanese - {'\u0030', '\u0039'}, // number - {'\u0061', '\u007a'}, // lower case - {'\u0041', '\u005a'}, // upper case -} - -const ( - ASCII = iota - MultiByte - CommonCJK - Chinese - Japanese - Number - LowerCase - UpperCase - - Random = 10000 -) - -// randChineseString makes a random string up to 20 characters long. The returned string -// may include a variety of (valid) UTF-8 encodings. Rand unicode: \u4e00 - \u9fa5 -func randChineseString(r *rand.Rand) string { - n := r.Intn(20) - sb := strings.Builder{} - sb.Grow(n) - for i := 0; i < n; i++ { - sb.WriteRune(unicodeRanges[3].choose(r)) - } - return sb.String() } // randString makes a random string up to 20 characters long. The returned string -// may include a variety of (valid) UTF-8 encodings. -func randString(r *rand.Rand, genMode int) string { +// may include a variety of (valid) UTF-8 encodings. If wants specific encoding +// string, it should input character range. +func randString(r *rand.Rand, characterRange *charRange) string { n := r.Intn(20) sb := strings.Builder{} sb.Grow(n) for i := 0; i < n; i++ { - if genMode == Random { + if characterRange == nil { sb.WriteRune(unicodeRanges[r.Intn(len(unicodeRanges))].choose(r)) } else { - sb.WriteRune(unicodeRanges[genMode].choose(r)) + sb.WriteRune(characterRange.choose(r)) } } return sb.String()