@@ -517,3 +517,78 @@ func TestClassify_Tokenize(t *testing.T) {
517517}
518518
519519func strPtr (s string ) * string { return & s }
520+
521+ func TestIsSystemPath (t * testing.T ) {
522+ // Regression: verify the extracted isSystemPath helper works correctly.
523+ tests := []struct {
524+ path string
525+ want bool
526+ }{
527+ {"/etc/hosts" , true },
528+ {"/usr/local/bin/go" , true },
529+ {"/bin/sh" , true },
530+ {"/lib/x86_64-linux-gnu/libc.so" , true },
531+ {"/var/log/syslog" , true },
532+ {"/opt/app/config" , true },
533+ {"/boot/vmlinuz" , true },
534+ {"/sbin/init" , true },
535+ {"/home/user/file" , false },
536+ {"/tmp/scratch" , false },
537+ {"/workspace/src" , false },
538+ {"./local/file" , false },
539+ {"file.go" , false },
540+ {"/root/.bashrc" , false },
541+ {"/usr" , false }, // no trailing slash — must be a directory prefix
542+ }
543+ for _ , tt := range tests {
544+ t .Run (tt .path , func (t * testing.T ) {
545+ got := isSystemPath (tt .path )
546+ if got != tt .want {
547+ t .Errorf ("isSystemPath(%q) = %v, want %v" , tt .path , got , tt .want )
548+ }
549+ })
550+ }
551+ }
552+
553+ func TestClassify_ForkBomb_StillDetected (t * testing.T ) {
554+ // Regression: fork bomb detection is now centralized in isRawBlocked.
555+ // Ensure it still works.
556+ tests := []struct {
557+ cmd string
558+ cls RiskClass
559+ }{
560+ {":(){ :|:& };:" , Blocked },
561+ // Variant with spaces in different places
562+ {" :(){ :|:& };: " , Blocked },
563+ }
564+ for _ , tt := range tests {
565+ t .Run (tt .cmd , func (t * testing.T ) {
566+ got := Classify (tt .cmd )
567+ if got != tt .cls {
568+ t .Errorf ("Classify(%q) = %s, want %s" , tt .cmd , got , tt .cls )
569+ }
570+ })
571+ }
572+ }
573+
574+ func TestClassify_SystemRedirectTarget (t * testing.T ) {
575+ // Regression: isSystemWrite and hasSystemRedirectTarget now share
576+ // isSystemPath. Verify system path redirect detection works.
577+ tests := []struct {
578+ cmd string
579+ cls RiskClass
580+ }{
581+ {"echo bad > /etc/hosts" , SystemWrite },
582+ {"cat data >> /usr/local/etc/app.conf" , SystemWrite },
583+ {"echo ok > /tmp/safe.txt" , LocalWrite },
584+ {"echo ok > ./local.conf" , LocalWrite },
585+ }
586+ for _ , tt := range tests {
587+ t .Run (tt .cmd , func (t * testing.T ) {
588+ got := Classify (tt .cmd )
589+ if got != tt .cls {
590+ t .Errorf ("Classify(%q) = %s, want %s" , tt .cmd , got , tt .cls )
591+ }
592+ })
593+ }
594+ }
0 commit comments