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 }