package dsl import ( "compress/gzip" "fmt" "io/ioutil" "regexp" "strings" "testing" "time" "github.com/Knetic/govaluate" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/projectdiscovery/nuclei/v2/pkg/types" ) func TestDSLURLEncodeDecode(t *testing.T) { functions := HelperFunctions() encoded, err := functions["url_encode"]("&test\"") require.Nil(t, err, "could not url encode") require.Equal(t, "%26test%22", encoded, "could not get url encoded data") decoded, err := functions["url_decode"]("%26test%22") require.Nil(t, err, "could not url encode") require.Equal(t, "&test\"", decoded, "could not get url decoded data") } func TestDSLTimeComparison(t *testing.T) { compiled, err := govaluate.NewEvaluableExpressionWithFunctions("unixtime() > not_after", HelperFunctions()) require.Nil(t, err, "could not compare time") result, err := compiled.Evaluate(map[string]interface{}{"not_after": float64(time.Now().Unix() - 1000)}) require.Nil(t, err, "could not evaluate compare time") require.Equal(t, true, result, "could not get url encoded data") } func TestDSLGzipSerialize(t *testing.T) { compiled, err := govaluate.NewEvaluableExpressionWithFunctions("gzip(\"hello world\")", HelperFunctions()) require.Nil(t, err, "could not compare time") result, err := compiled.Evaluate(make(map[string]interface{})) require.Nil(t, err, "could not evaluate compare time") reader, _ := gzip.NewReader(strings.NewReader(types.ToString(result))) data, _ := ioutil.ReadAll(reader) require.Equal(t, "hello world", string(data), "could not get gzip encoded data") } func Test1(t *testing.T) { type testCase struct { methodName string arguments []interface{} expected interface{} err string } toUpperSignatureError := createSignatureError("to_upper(arg1 interface{}) interface{}") removeBadCharsSignatureError := createSignatureError("remove_bad_chars(arg1, arg2 interface{}) interface{}") testCases := []testCase{ {"to_upper", []interface{}{}, nil, toUpperSignatureError}, {"to_upper", []interface{}{"a"}, "A", ""}, {"toupper", []interface{}{"a"}, "A", ""}, {"to_upper", []interface{}{"a", "b", "c"}, nil, toUpperSignatureError}, {"remove_bad_chars", []interface{}{}, nil, removeBadCharsSignatureError}, {"remove_bad_chars", []interface{}{"a"}, nil, removeBadCharsSignatureError}, {"remove_bad_chars", []interface{}{"abba baab", "b"}, "aa aa", ""}, {"remove_bad_chars", []interface{}{"a", "b", "c"}, nil, removeBadCharsSignatureError}, } helperFunctions := HelperFunctions() for _, currentTestCase := range testCases { methodName := currentTestCase.methodName t.Run(methodName, func(t *testing.T) { actualResult, err := helperFunctions[methodName](currentTestCase.arguments...) if currentTestCase.err == "" { assert.Nil(t, err) } else { assert.Equal(t, err.Error(), currentTestCase.err) } assert.Equal(t, currentTestCase.expected, actualResult) }) } } func createSignatureError(signature string) string { return fmt.Errorf(invalidDslFunctionMessageTemplate, invalidDslFunctionError, signature).Error() } func TestGetPrintableDslFunctionSignatures(t *testing.T) { expected := ` base64(arg1 interface{}) interface{} base64_decode(arg1 interface{}) interface{} base64_py(arg1 interface{}) interface{} contains(arg1, arg2 interface{}) interface{} generate_java_gadget(arg1, arg2, arg3 interface{}) interface{} gzip(arg1 interface{}) interface{} hex_decode(arg1 interface{}) interface{} hex_encode(arg1 interface{}) interface{} html_escape(arg1 interface{}) interface{} html_unescape(arg1 interface{}) interface{} len(arg1 interface{}) interface{} md5(arg1 interface{}) interface{} mmh3(arg1 interface{}) interface{} print_debug(args ...interface{}) rand_base(length uint, optionalCharSet string) string rand_char(optionalCharSet string) string rand_int(optionalMin, optionalMax uint) int rand_text_alpha(length uint, optionalBadChars string) string rand_text_alphanumeric(length uint, optionalBadChars string) string rand_text_numeric(length uint, optionalBadNumbers string) string regex(arg1, arg2 interface{}) interface{} remove_bad_chars(arg1, arg2 interface{}) interface{} replace(arg1, arg2, arg3 interface{}) interface{} replace_regex(arg1, arg2, arg3 interface{}) interface{} reverse(arg1 interface{}) interface{} sha1(arg1 interface{}) interface{} sha256(arg1 interface{}) interface{} to_lower(arg1 interface{}) interface{} to_upper(arg1 interface{}) interface{} trim(arg1, arg2 interface{}) interface{} trim_left(arg1, arg2 interface{}) interface{} trim_prefix(arg1, arg2 interface{}) interface{} trim_right(arg1, arg2 interface{}) interface{} trim_space(arg1 interface{}) interface{} trim_suffix(arg1, arg2 interface{}) interface{} unix_time(optionalSeconds uint) float64 url_decode(arg1 interface{}) interface{} url_encode(arg1 interface{}) interface{} wait_for(seconds uint) ` t.Run("with coloring", func(t *testing.T) { assert.Equal(t, expected, GetPrintableDslFunctionSignatures(false)) }) t.Run("without coloring", func(t *testing.T) { var decolorizerRegex = regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) expectedSignaturesWithoutColor := decolorizerRegex.ReplaceAllString(expected, "") assert.Equal(t, expectedSignaturesWithoutColor, GetPrintableDslFunctionSignatures(true)) }) }