From de068eafa3686bcb80b6f285f7e4d9bcf9f69b34 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 20 Jul 2025 12:13:01 +0000 Subject: [PATCH 1/2] Initial plan From b673bfaacb78c977320cf0cab8a231e98edfce1a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 20 Jul 2025 12:21:12 +0000 Subject: [PATCH 2/2] Implement edge case handling for name query parameter Co-authored-by: nofarblue <96581654+nofarblue@users.noreply.github.com> --- hello_server.go | 26 ++++++++++++- hello_server_test.go | 91 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 3 deletions(-) diff --git a/hello_server.go b/hello_server.go index df038fd..7109ea6 100644 --- a/hello_server.go +++ b/hello_server.go @@ -6,6 +6,8 @@ import ( "net/http" "os" "os/signal" + "regexp" + "strings" "syscall" "time" @@ -15,14 +17,34 @@ import ( func handler(w http.ResponseWriter, r *http.Request) { query := r.URL.Query() name := query.Get("name") - log.Printf("Received request for %s\n", name) + + // Sanitize name for logging by removing control characters + controlCharsRegex := regexp.MustCompile(`[\x00-\x1F\x7F]`) + sanitizedName := controlCharsRegex.ReplaceAllString(name, " ") + + log.Printf("Received request for %s\n", sanitizedName) w.Write([]byte(CreateGreeting(name))) } func CreateGreeting(name string) string { + // Trim leading and trailing whitespace + name = strings.TrimSpace(name) + + // Return "Hello, Guest" if input is empty after trim if name == "" { - name = "Guest" + return "Hello, Guest\n" } + + // Limit accepted name length to 100 characters + if len(name) > 100 { + name = name[:100] + } + + // Strip newline and control characters, replace with space + // This regex matches control characters (ASCII 0-31) except space (32) + controlCharsRegex := regexp.MustCompile(`[\x00-\x1F\x7F]`) + name = controlCharsRegex.ReplaceAllString(name, " ") + return "Hello, " + name + "\n" } diff --git a/hello_server_test.go b/hello_server_test.go index a3f5cd3..d27c45a 100644 --- a/hello_server_test.go +++ b/hello_server_test.go @@ -36,6 +36,95 @@ func TestGreetingDefault(t *testing.T) { t.Errorf("Greeting was incorrect, got: %s, want: %s.", greeting, "Hello, Guest\n") } } - +func TestGreeting_WhitespaceOnly(t *testing.T) { + testCases := []string{ + " ", // spaces + "\t", // tab + "\n", // newline + "\r", // carriage return + " \t\n\r ", // mixed whitespace + } + + for _, name := range testCases { + greeting := CreateGreeting(name) + if greeting != "Hello, Guest\n" { + t.Errorf("Greeting for whitespace-only name '%s' was incorrect, got: %s, want: %s.", name, greeting, "Hello, Guest\n") + } + } +} + +func TestGreeting_LongName(t *testing.T) { + // Test name longer than 100 characters + longName := "a" + for i := 0; i < 120; i++ { + longName += "a" + } + + greeting := CreateGreeting(longName) + // Should truncate to 100 characters + expectedName := longName[:100] + expected := "Hello, " + expectedName + "\n" + + if greeting != expected { + t.Errorf("Greeting for long name was incorrect, got length %d, want length %d", len(greeting)-8-1, 100) // -8 for "Hello, " and -1 for "\n" + } +} + +func TestGreeting_NewlineInjection(t *testing.T) { + testCases := []struct { + input string + expected string + }{ + {"John\nAdmin", "Hello, John Admin\n"}, // newline should be replaced with space + {"Jane\r\nDoe", "Hello, Jane Doe\n"}, // carriage return + newline + {"Test\tUser", "Hello, Test User\n"}, // tab should be replaced with space + {"User\x00", "Hello, User \n"}, // null character + {"Test\x01\x02", "Hello, Test \n"}, // control characters + } + + for _, tc := range testCases { + greeting := CreateGreeting(tc.input) + if greeting != tc.expected { + t.Errorf("Greeting for input '%s' was incorrect, got: %s, want: %s.", tc.input, greeting, tc.expected) + } + } +} + +func TestGreeting_SpecialSymbols(t *testing.T) { + testCases := []struct { + input string + expected string + }{ + {"Jane!@#", "Hello, Jane!@#\n"}, + {"User$%^&*()", "Hello, User$%^&*()\n"}, + {"Test-User_123", "Hello, Test-User_123\n"}, + {"João", "Hello, João\n"}, // Unicode characters should be preserved + } + + for _, tc := range testCases { + greeting := CreateGreeting(tc.input) + if greeting != tc.expected { + t.Errorf("Greeting for input '%s' was incorrect, got: %s, want: %s.", tc.input, greeting, tc.expected) + } + } +} + +func TestGreeting_TrimWhitespace(t *testing.T) { + testCases := []struct { + input string + expected string + }{ + {" John ", "Hello, John\n"}, + {"\tJane\t", "Hello, Jane\n"}, + {" \n Test \r ", "Hello, Test\n"}, + } + + for _, tc := range testCases { + greeting := CreateGreeting(tc.input) + if greeting != tc.expected { + t.Errorf("Greeting for input '%s' was incorrect, got: %s, want: %s.", tc.input, greeting, tc.expected) + } + } +}