From 3aa5c91c23b022c109b6889001df65ca0df7ee3b Mon Sep 17 00:00:00 2001 From: ivan katliarchuk Date: Fri, 5 Jul 2024 20:15:38 +0100 Subject: [PATCH] fix(issue-4448): added another flavour of same function with tests Signed-off-by: ivan katliarchuk --- provider/aws/aws.go | 54 ++++++++++++++++++++++++++++++++++++++++ provider/aws/aws_test.go | 40 ++++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/provider/aws/aws.go b/provider/aws/aws.go index c005cc78c..29befd2de 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -416,6 +416,7 @@ func convertOctalToAscii(input string) string { if input[i] == '\\' && i+3 < len(input) { octalStr := input[i+1 : i+4] if octal, err := strconv.ParseInt(octalStr, 8, 8); err == nil { + fmt.Println("string:", octalStr, " char:", byte(octal)) result.WriteByte(byte(octal)) i += 3 // Skip the next 3 characters (the octal code) } else { @@ -428,6 +429,59 @@ func convertOctalToAscii(input string) string { return result.String() } +var octalCharTable = map[string]byte{ + "041": byte(33), // exclamation mark + "042": byte(34), // double quote + "043": byte(35), // # number sing + "044": byte(36), // $ dollar + "045": byte(37), // % percentage + "046": byte(38), // & ampersand + "047": byte(39), // single quote + "050": byte(40), // ( left parenthesis + "051": byte(41), // ) right parenthesis + "052": byte(42), // * asterisk + "053": byte(43), // + plus + "054": byte(44), // , comma + "057": byte(47), // / forward slash + "072": byte(58), // : colon + "073": byte(59), // ; semicolon + "074": byte(60), // < less than sign + "075": byte(61), // = equal + "076": byte(62), // > greater than sign + "077": byte(63), // question mark + "100": byte(64), // @ at symbol + "133": byte(91), // [ left square bracket + "134": byte(92), // ] right square bracket + "135": byte(93), // ^ caret + "136": byte(94), // _ underscore + "140": byte(96), // ` backtick + "173": byte(123), // { left curly brace + "174": byte(124), // | vertical baar + "175": byte(125), // } right curly brace + "176": byte(126), // tilda +} + +func convertOctalToAsciiWithHashTable(input string) string { + if !containsOctalSequence(input) { + return input + } + var result strings.Builder + for i := 0; i < len(input); i++ { + if input[i] == '\\' && i+3 < len(input) { + octalStr := input[i+1 : i+4] + if char, ok := octalCharTable[octalStr]; ok { + result.WriteByte(char) + i += 3 // Skip the next 3 characters (the octal code) + } else { + result.WriteString(input[i : i+4]) // Keep the entire sequence if not found + } + } else { + result.WriteByte(input[i]) + } + } + return result.String() +} + // validateDomainName checks if the domain name contains valid octal escape sequences. func containsOctalSequence(domain string) bool { // Pattern to match valid octal escape sequences diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index e813fcf05..e74250ee3 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -386,9 +386,9 @@ func TestAWSRecords(t *testing.T) { ResourceRecords: []*route53.ResourceRecord{{Value: aws.String("1.2.3.4")}}, }, { - Name: aws.String(specialCharactersEscape("escape-%!s()-codes-alias.zone-2.ext-dns-test-2.teapot.zalan.do.")), - Type: aws.String(route53.RRTypeA), - TTL: aws.Int64(recordTTL), + Name: aws.String(specialCharactersEscape("escape-%!s()-codes-alias.zone-2.ext-dns-test-2.teapot.zalan.do.")), + Type: aws.String(route53.RRTypeA), + TTL: aws.Int64(recordTTL), AliasTarget: &route53.AliasTarget{ DNSName: aws.String("escape-codes.eu-central-1.elb.amazonaws.com."), EvaluateTargetHealth: aws.Bool(false), @@ -2084,3 +2084,37 @@ func TestRequiresDeleteCreate(t *testing.T) { assert.False(t, provider.requiresDeleteCreate(oldSetIdentifier, oldSetIdentifier), "actual and expected endpoints don't match. %+v:%+v", oldSetIdentifier, oldSetIdentifier) assert.True(t, provider.requiresDeleteCreate(oldSetIdentifier, newSetIdentifier), "actual and expected endpoints don't match. %+v:%+v", oldSetIdentifier, newSetIdentifier) } + +func TestConvertOctalToAscii(t *testing.T) { + tests := []struct { + name string + input string + expected string + }{ + { + name: "Characters escaped !\"#$%&'()*+,-/:;", + input: "txt-\\041\\042\\043\\044\\045\\046\\047\\050\\051\\052\\053\\054-\\057\\072\\073-test.example.com", + expected: "txt-!\"#$%&'()*+,-/:;-test.example.com", + }, + { + name: "Characters escaped <=>?@[\\]^_`{|}~", + input: "txt-\\074\\075\\076\\077\\100\\133\\134\\135\\136_\\140\\173\\174\\175\\176-test2.example.com", + expected: "txt-<=>?@[\\]^_`{|}~-test2.example.com", + }, + { + name: "No escaped characters in domain", + input: "txt-awesome-test3.example.com", + expected: "txt-awesome-test3.example.com", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // actual := convertOctalToAscii(tt.input) + // assert.Equal(t, tt.expected, actual) + + actualv := convertOctalToAsciiWithHashTable(tt.input) + assert.Equal(t, tt.expected, actualv) + }) + } +}