Skip to content

Commit 4794128

Browse files
Copilotshueybubbles
andcommitted
Fix UTF-8 handling in ADO connection string parsing
Replace WriteByte with WriteRune in splitAdoConnectionStringParts to properly handle multibyte UTF-8 characters. Add comprehensive test cases with Cyrillic, Chinese, emoji, and accented characters in quoted connection string values. Co-authored-by: shueybubbles <[email protected]>
1 parent f1c1028 commit 4794128

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

msdsn/conn_str.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -712,26 +712,27 @@ func splitAdoConnectionStringParts(dsn string) []string {
712712
var current strings.Builder
713713
inQuotes := false
714714

715-
for i := 0; i < len(dsn); i++ {
716-
char := dsn[i]
715+
runes := []rune(dsn)
716+
for i := 0; i < len(runes); i++ {
717+
char := runes[i]
717718

718719
if char == '"' {
719-
if inQuotes && i+1 < len(dsn) && dsn[i+1] == '"' {
720+
if inQuotes && i+1 < len(runes) && runes[i+1] == '"' {
720721
// Double quote escape sequence - add both quotes to current part
721-
current.WriteByte(char)
722-
current.WriteByte(dsn[i+1])
722+
current.WriteRune(char)
723+
current.WriteRune(runes[i+1])
723724
i++ // Skip the next quote
724725
} else {
725726
// Start or end of quoted section
726727
inQuotes = !inQuotes
727-
current.WriteByte(char)
728+
current.WriteRune(char)
728729
}
729730
} else if char == ';' && !inQuotes {
730731
// Semicolon outside of quotes - end current part
731732
parts = append(parts, current.String())
732733
current.Reset()
733734
} else {
734-
current.WriteByte(char)
735+
current.WriteRune(char)
735736
}
736737
}
737738

msdsn/conn_str_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,14 @@ func TestValidConnectionString(t *testing.T) {
130130
{"password=\";;\"", func(p Config) bool { return p.Password == ";;" }}, // Multiple semicolons
131131
{"server=\"host;name\";password=\"pass;word\"", func(p Config) bool { return p.Host == "host;name" && p.Password == "pass;word" }}, // Multiple quoted values
132132

133+
// Test cases with multibyte UTF-8 characters
134+
{"password=\"пароль;test\"", func(p Config) bool { return p.Password == "пароль;test" }}, // Cyrillic characters with semicolon
135+
{"server=\"服务器;name\";password=\"密码;word\"", func(p Config) bool { return p.Host == "服务器;name" && p.Password == "密码;word" }}, // Chinese characters
136+
{"password=\"🔐;secret;🗝️\"", func(p Config) bool { return p.Password == "🔐;secret;🗝️" }}, // Emoji characters with semicolons
137+
{"user id=\"用户名\";password=\"пароль\"", func(p Config) bool { return p.User == "用户名" && p.Password == "пароль" }}, // Mixed multibyte chars
138+
{"password=\"测试\"\"密码\"\"\"", func(p Config) bool { return p.Password == "测试\"密码\"" }}, // Chinese chars with escaped quotes
139+
{"password=\"café;naïve;résumé\"", func(p Config) bool { return p.Password == "café;naïve;résumé" }}, // Accented characters
140+
133141
// those are supported currently, but maybe should not be
134142
{"someparam", func(p Config) bool { return true }},
135143
{";;=;", func(p Config) bool { return true }},

0 commit comments

Comments
 (0)