github.com/terraform-linters/tflint@v0.51.2-0.20240520175844-3750771571b6/terraform/lang/funcs/encoding_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package funcs
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  
    10  	"github.com/terraform-linters/tflint-plugin-sdk/terraform/lang/marks"
    11  	"github.com/zclconf/go-cty/cty"
    12  )
    13  
    14  func TestBase64Decode(t *testing.T) {
    15  	tests := []struct {
    16  		String cty.Value
    17  		Want   cty.Value
    18  		Err    bool
    19  	}{
    20  		{
    21  			cty.StringVal("YWJjMTIzIT8kKiYoKSctPUB+"),
    22  			cty.StringVal("abc123!?$*&()'-=@~"),
    23  			false,
    24  		},
    25  		{
    26  			cty.StringVal("YWJjMTIzIT8kKiYoKSctPUB+").Mark(marks.Sensitive),
    27  			cty.StringVal("abc123!?$*&()'-=@~").Mark(marks.Sensitive),
    28  			false,
    29  		},
    30  		{ // Invalid base64 data decoding
    31  			cty.StringVal("this-is-an-invalid-base64-data"),
    32  			cty.UnknownVal(cty.String),
    33  			true,
    34  		},
    35  		{ // Invalid utf-8
    36  			cty.StringVal("\xc3\x28"),
    37  			cty.UnknownVal(cty.String),
    38  			true,
    39  		},
    40  	}
    41  
    42  	for _, test := range tests {
    43  		t.Run(fmt.Sprintf("base64decode(%#v)", test.String), func(t *testing.T) {
    44  			got, err := Base64Decode(test.String)
    45  
    46  			if test.Err {
    47  				if err == nil {
    48  					t.Fatal("succeeded; want error")
    49  				}
    50  				return
    51  			} else if err != nil {
    52  				t.Fatalf("unexpected error: %s", err)
    53  			}
    54  
    55  			if !got.RawEquals(test.Want) {
    56  				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
    57  			}
    58  		})
    59  	}
    60  }
    61  
    62  func TestBase64Decode_error(t *testing.T) {
    63  	tests := map[string]struct {
    64  		String  cty.Value
    65  		WantErr string
    66  	}{
    67  		"invalid base64": {
    68  			cty.StringVal("dfg"),
    69  			`failed to decode base64 data "dfg"`,
    70  		},
    71  		"sensitive invalid base64": {
    72  			cty.StringVal("dfg").Mark(marks.Sensitive),
    73  			`failed to decode base64 data (sensitive value)`,
    74  		},
    75  		"invalid utf-8": {
    76  			cty.StringVal("whee"),
    77  			"the result of decoding the provided string is not valid UTF-8",
    78  		},
    79  	}
    80  
    81  	for name, test := range tests {
    82  		t.Run(name, func(t *testing.T) {
    83  			_, err := Base64Decode(test.String)
    84  
    85  			if err == nil {
    86  				t.Fatal("succeeded; want error")
    87  			}
    88  
    89  			if err.Error() != test.WantErr {
    90  				t.Errorf("wrong error result\ngot:  %#v\nwant: %#v", err.Error(), test.WantErr)
    91  			}
    92  		})
    93  	}
    94  }
    95  
    96  func TestBase64Encode(t *testing.T) {
    97  	tests := []struct {
    98  		String cty.Value
    99  		Want   cty.Value
   100  		Err    bool
   101  	}{
   102  		{
   103  			cty.StringVal("abc123!?$*&()'-=@~"),
   104  			cty.StringVal("YWJjMTIzIT8kKiYoKSctPUB+"),
   105  			false,
   106  		},
   107  	}
   108  
   109  	for _, test := range tests {
   110  		t.Run(fmt.Sprintf("base64encode(%#v)", test.String), func(t *testing.T) {
   111  			got, err := Base64Encode(test.String)
   112  
   113  			if test.Err {
   114  				if err == nil {
   115  					t.Fatal("succeeded; want error")
   116  				}
   117  				return
   118  			} else if err != nil {
   119  				t.Fatalf("unexpected error: %s", err)
   120  			}
   121  
   122  			if !got.RawEquals(test.Want) {
   123  				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
   124  			}
   125  		})
   126  	}
   127  }
   128  
   129  func TestBase64Gzip(t *testing.T) {
   130  	tests := []struct {
   131  		String cty.Value
   132  		Want   cty.Value
   133  		Err    bool
   134  	}{
   135  		{
   136  			cty.StringVal("test"),
   137  			cty.StringVal("H4sIAAAAAAAA/ypJLS4BAAAA//8BAAD//wx+f9gEAAAA"),
   138  			false,
   139  		},
   140  	}
   141  
   142  	for _, test := range tests {
   143  		t.Run(fmt.Sprintf("base64gzip(%#v)", test.String), func(t *testing.T) {
   144  			got, err := Base64Gzip(test.String)
   145  
   146  			if test.Err {
   147  				if err == nil {
   148  					t.Fatal("succeeded; want error")
   149  				}
   150  				return
   151  			} else if err != nil {
   152  				t.Fatalf("unexpected error: %s", err)
   153  			}
   154  
   155  			if !got.RawEquals(test.Want) {
   156  				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
   157  			}
   158  		})
   159  	}
   160  }
   161  
   162  func TestURLEncode(t *testing.T) {
   163  	tests := []struct {
   164  		String cty.Value
   165  		Want   cty.Value
   166  		Err    bool
   167  	}{
   168  		{
   169  			cty.StringVal("abc123-_"),
   170  			cty.StringVal("abc123-_"),
   171  			false,
   172  		},
   173  		{
   174  			cty.StringVal("foo:bar@localhost?foo=bar&bar=baz"),
   175  			cty.StringVal("foo%3Abar%40localhost%3Ffoo%3Dbar%26bar%3Dbaz"),
   176  			false,
   177  		},
   178  		{
   179  			cty.StringVal("mailto:email?subject=this+is+my+subject"),
   180  			cty.StringVal("mailto%3Aemail%3Fsubject%3Dthis%2Bis%2Bmy%2Bsubject"),
   181  			false,
   182  		},
   183  		{
   184  			cty.StringVal("foo/bar"),
   185  			cty.StringVal("foo%2Fbar"),
   186  			false,
   187  		},
   188  	}
   189  
   190  	for _, test := range tests {
   191  		t.Run(fmt.Sprintf("urlencode(%#v)", test.String), func(t *testing.T) {
   192  			got, err := URLEncode(test.String)
   193  
   194  			if test.Err {
   195  				if err == nil {
   196  					t.Fatal("succeeded; want error")
   197  				}
   198  				return
   199  			} else if err != nil {
   200  				t.Fatalf("unexpected error: %s", err)
   201  			}
   202  
   203  			if !got.RawEquals(test.Want) {
   204  				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
   205  			}
   206  		})
   207  	}
   208  }
   209  
   210  func TestBase64TextEncode(t *testing.T) {
   211  	tests := []struct {
   212  		String   cty.Value
   213  		Encoding cty.Value
   214  		Want     cty.Value
   215  		Err      string
   216  	}{
   217  		{
   218  			cty.StringVal("abc123!?$*&()'-=@~"),
   219  			cty.StringVal("UTF-8"),
   220  			cty.StringVal("YWJjMTIzIT8kKiYoKSctPUB+"),
   221  			``,
   222  		},
   223  		{
   224  			cty.StringVal("abc123!?$*&()'-=@~"),
   225  			cty.StringVal("UTF-16LE"),
   226  			cty.StringVal("YQBiAGMAMQAyADMAIQA/ACQAKgAmACgAKQAnAC0APQBAAH4A"),
   227  			``,
   228  		},
   229  		{
   230  			cty.StringVal("abc123!?$*&()'-=@~"),
   231  			cty.StringVal("CP936"),
   232  			cty.StringVal("YWJjMTIzIT8kKiYoKSctPUB+"),
   233  			``,
   234  		},
   235  		{
   236  			cty.StringVal("abc123!?$*&()'-=@~"),
   237  			cty.StringVal("NOT-EXISTS"),
   238  			cty.UnknownVal(cty.String).RefineNotNull(),
   239  			`"NOT-EXISTS" is not a supported IANA encoding name or alias in this Terraform version`,
   240  		},
   241  		{
   242  			cty.StringVal("🤔"),
   243  			cty.StringVal("cp437"),
   244  			cty.UnknownVal(cty.String).RefineNotNull(),
   245  			`the given string contains characters that cannot be represented in IBM437`,
   246  		},
   247  		{
   248  			cty.UnknownVal(cty.String),
   249  			cty.StringVal("windows-1250"),
   250  			cty.UnknownVal(cty.String).RefineNotNull(),
   251  			``,
   252  		},
   253  		{
   254  			cty.StringVal("hello world"),
   255  			cty.UnknownVal(cty.String),
   256  			cty.UnknownVal(cty.String).RefineNotNull(),
   257  			``,
   258  		},
   259  	}
   260  
   261  	for _, test := range tests {
   262  		t.Run(fmt.Sprintf("textencodebase64(%#v, %#v)", test.String, test.Encoding), func(t *testing.T) {
   263  			got, err := TextEncodeBase64(test.String, test.Encoding)
   264  
   265  			if test.Err != "" {
   266  				if err == nil {
   267  					t.Fatal("succeeded; want error")
   268  				}
   269  				if got, want := err.Error(), test.Err; got != want {
   270  					t.Fatalf("wrong error\ngot:  %s\nwant: %s", got, want)
   271  				}
   272  				return
   273  			} else if err != nil {
   274  				t.Fatalf("unexpected error: %s", err)
   275  			}
   276  
   277  			if !got.RawEquals(test.Want) {
   278  				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
   279  			}
   280  		})
   281  	}
   282  }
   283  
   284  func TestBase64TextDecode(t *testing.T) {
   285  	tests := []struct {
   286  		String   cty.Value
   287  		Encoding cty.Value
   288  		Want     cty.Value
   289  		Err      string
   290  	}{
   291  		{
   292  			cty.StringVal("YWJjMTIzIT8kKiYoKSctPUB+"),
   293  			cty.StringVal("UTF-8"),
   294  			cty.StringVal("abc123!?$*&()'-=@~"),
   295  			``,
   296  		},
   297  		{
   298  			cty.StringVal("YQBiAGMAMQAyADMAIQA/ACQAKgAmACgAKQAnAC0APQBAAH4A"),
   299  			cty.StringVal("UTF-16LE"),
   300  			cty.StringVal("abc123!?$*&()'-=@~"),
   301  			``,
   302  		},
   303  		{
   304  			cty.StringVal("YWJjMTIzIT8kKiYoKSctPUB+"),
   305  			cty.StringVal("CP936"),
   306  			cty.StringVal("abc123!?$*&()'-=@~"),
   307  			``,
   308  		},
   309  		{
   310  			cty.StringVal("doesn't matter"),
   311  			cty.StringVal("NOT-EXISTS"),
   312  			cty.UnknownVal(cty.String).RefineNotNull(),
   313  			`"NOT-EXISTS" is not a supported IANA encoding name or alias in this Terraform version`,
   314  		},
   315  		{
   316  			cty.StringVal("<invalid base64>"),
   317  			cty.StringVal("cp437"),
   318  			cty.UnknownVal(cty.String).RefineNotNull(),
   319  			`the given value is has an invalid base64 symbol at offset 0`,
   320  		},
   321  		{
   322  			cty.StringVal("gQ=="), // this is 0x81, which is not defined in windows-1250
   323  			cty.StringVal("windows-1250"),
   324  			cty.StringVal("�"),
   325  			`the given string contains symbols that are not defined for windows-1250`,
   326  		},
   327  		{
   328  			cty.UnknownVal(cty.String),
   329  			cty.StringVal("windows-1250"),
   330  			cty.UnknownVal(cty.String).RefineNotNull(),
   331  			``,
   332  		},
   333  		{
   334  			cty.StringVal("YQBiAGMAMQAyADMAIQA/ACQAKgAmACgAKQAnAC0APQBAAH4A"),
   335  			cty.UnknownVal(cty.String),
   336  			cty.UnknownVal(cty.String).RefineNotNull(),
   337  			``,
   338  		},
   339  	}
   340  
   341  	for _, test := range tests {
   342  		t.Run(fmt.Sprintf("textdecodebase64(%#v, %#v)", test.String, test.Encoding), func(t *testing.T) {
   343  			got, err := TextDecodeBase64(test.String, test.Encoding)
   344  
   345  			if test.Err != "" {
   346  				if err == nil {
   347  					t.Fatal("succeeded; want error")
   348  				}
   349  				if got, want := err.Error(), test.Err; got != want {
   350  					t.Fatalf("wrong error\ngot:  %s\nwant: %s", got, want)
   351  				}
   352  				return
   353  			} else if err != nil {
   354  				t.Fatalf("unexpected error: %s", err)
   355  			}
   356  
   357  			if !got.RawEquals(test.Want) {
   358  				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
   359  			}
   360  		})
   361  	}
   362  }