Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions hello_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"net/http"
"os"
"os/signal"
"regexp"
"strings"
"syscall"
"time"

Expand All @@ -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"
}

Expand Down
91 changes: 90 additions & 1 deletion hello_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}