mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-07 15:38:22 +08:00
feat(security-audit): allow Qwen3Guard auxiliary fields
This commit is contained in:
@@ -86,19 +86,13 @@ func NormalizeCategory(value string) string {
|
||||
}
|
||||
|
||||
func ParseQwen3Guard(content string, enabledScanners []string) (*NormalizedResult, error) {
|
||||
lines := make([]string, 0, 2)
|
||||
for _, line := range strings.Split(strings.ReplaceAll(content, "\r\n", "\n"), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line != "" {
|
||||
lines = append(lines, line)
|
||||
}
|
||||
}
|
||||
if len(lines) != 2 {
|
||||
return nil, &GuardError{Code: ErrorCodeInvalidResponse, Retryable: false}
|
||||
}
|
||||
var safety string
|
||||
var categoryLine string
|
||||
for _, line := range lines {
|
||||
for _, line := range strings.Split(strings.ReplaceAll(content, "\r\n", "\n"), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
lower := strings.ToLower(line)
|
||||
switch {
|
||||
case strings.HasPrefix(lower, "safety:"):
|
||||
@@ -112,7 +106,7 @@ func ParseQwen3Guard(content string, enabledScanners []string) (*NormalizedResul
|
||||
}
|
||||
categoryLine = strings.TrimSpace(line[len("categories:"):])
|
||||
default:
|
||||
return nil, &GuardError{Code: ErrorCodeInvalidResponse}
|
||||
// Auxiliary Guard fields, such as Refusal, do not affect audit decisions.
|
||||
}
|
||||
}
|
||||
switch strings.ToLower(safety) {
|
||||
|
||||
@@ -22,7 +22,7 @@ func TestParseQwen3GuardStrictAndPolicy(t *testing.T) {
|
||||
{"unsafe", "Safety: Unsafe\nCategories: Jailbreak", AllScannerIDs, EventCritical, ActionBlock, false},
|
||||
{"unknown unsafe", "Safety: Unsafe\nCategories: Future Risk", AllScannerIDs, EventCritical, ActionBlock, false},
|
||||
{"disabled unsafe warns", "Safety: Unsafe\nCategories: Violent", []string{"PII"}, EventFlag, ActionWarn, false},
|
||||
{"extra explanation", "Safety: Safe\nCategories: None\nThis is safe", AllScannerIDs, "", "", true},
|
||||
{"extra explanation", "Safety: Safe\nCategories: None\nThis is safe", AllScannerIDs, EventPass, ActionAllow, false},
|
||||
{"duplicate", "Safety: Safe\nSafety: Safe", AllScannerIDs, "", "", true},
|
||||
{"duplicate categories", "Safety: Safe\nCategories: None\nCategories: PII", AllScannerIDs, "", "", true},
|
||||
{"missing categories", "Safety: Safe\n", AllScannerIDs, "", "", true},
|
||||
@@ -42,6 +42,18 @@ func TestParseQwen3GuardStrictAndPolicy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseQwen3GuardIgnoresAuxiliaryResponseFields(t *testing.T) {
|
||||
result, err := ParseQwen3Guard("Safety: Unsafe\nCategories: Jailbreak\nRefusal: No", AllScannerIDs)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "Unsafe", result.Safety)
|
||||
require.Equal(t, []string{"jailbreak"}, result.Categories)
|
||||
|
||||
serialized, err := json.Marshal(result)
|
||||
require.NoError(t, err)
|
||||
require.NotContains(t, string(serialized), "Refusal")
|
||||
require.NotContains(t, string(serialized), "No")
|
||||
}
|
||||
|
||||
func TestQwen3GuardOfficialCategoriesAliasesAndUnknownAreStable(t *testing.T) {
|
||||
official := "Violent, Non-violent Illegal Acts, Sexual Content or Sexual Acts, PII, Suicide & Self-Harm, Unethical Acts, Politically Sensitive Topics, Copyright Violation, Jailbreak"
|
||||
result, err := ParseQwen3Guard("Safety: Unsafe\nCategories: "+official, AllScannerIDs)
|
||||
|
||||
Reference in New Issue
Block a user