feat(nas): handle wenc/wregion in the profanity check endpoint

This commit is contained in:
Jonathan Barrow 2026-01-12 13:53:09 -05:00
parent 42a3a362a6
commit ca8c9f1931
No known key found for this signature in database
GPG Key ID: 2A7DAA6DED5A77E5

View File

@ -122,7 +122,7 @@ func handleAuthRequest(moduleName string, w http.ResponseWriter, r *http.Request
return
}
reply = handleProfanity(fields)
reply = handleProfanity(r.PostForm, unitcd)
} else if r.URL.String() == "/download" {
action, ok := fields["action"]
if !ok || action == "" {
@ -356,9 +356,77 @@ func svcloc(fields map[string]string) map[string]string {
return param
}
func handleProfanity(fields map[string]string) map[string]string {
func handleProfanity(form url.Values, unitcd string) map[string]string {
var wordsEncoding string
var wordsDefaultEncoding string
var wordsBytes []byte
var words string
var wordsRegion string
var prwords string
for _, word := range strings.Split(fields["words"], "\t") {
if unitcd == "0" {
wordsEncoding = "UTF-16LE"
wordsDefaultEncoding = "UTF-16LE"
} else {
wordsEncoding = "UTF-16BE"
wordsDefaultEncoding = "UTF-16BE"
}
if wencValues, ok := form["wenc"]; ok {
// It's okay for this to error, the real server
// just falls back to the default encoding in
// this case even if it cant properly handle it
wencDecoded, err := common.Base64DwcEncoding.DecodeString(wencValues[0])
if err == nil {
wordsEncoding = string(wencDecoded)
}
}
if wordsEncoding != "UTF-8" && wordsEncoding != "UTF-16LE" && wordsEncoding != "UTF-16BE" {
wordsEncoding = wordsDefaultEncoding
}
// It's okay for this to not exist/be valid, the real
// server will just treat the missing input as a single
// non-profane word
if wordsValues, ok := form["words"]; ok {
wordsDecoded, err := common.Base64DwcEncoding.DecodeString(wordsValues[0])
if err == nil {
wordsBytes = wordsDecoded
}
}
// This field is entirely optional, unsure what
// specifically it does. Adds extra data to the
// reply, probably used for handling the word
// list differently for different regions?
if wordsRegionValues, ok := form["wregion"]; ok {
wordsRegionDecoded, err := common.Base64DwcEncoding.DecodeString(wordsRegionValues[0])
if err == nil {
wordsRegion = string(wordsRegionDecoded)
}
}
if wordsEncoding == "UTF-8" {
words = string(wordsBytes)
} else {
var utf16String []uint16
if unitcd == "0" {
for i := 0; i < len(wordsBytes)/2; i++ {
utf16String = append(utf16String, binary.LittleEndian.Uint16(wordsBytes[i*2:i*2+2]))
}
} else {
for i := 0; i < len(wordsBytes)/2; i++ {
utf16String = append(utf16String, binary.BigEndian.Uint16(wordsBytes[i*2:i*2+2]))
}
}
words = string(utf16.Decode(utf16String))
}
// TODO - Handle wtype? Unsure what this field does, seems to always be an emtpy string
for _, word := range strings.Split(words, "\t") {
if isBadWord, _ := IsBadWord(word); isBadWord {
prwords += "1"
} else {
@ -373,10 +441,23 @@ func handleProfanity(fields map[string]string) map[string]string {
returncd = "000"
}
return map[string]string{
reply := map[string]string{
"returncd": returncd,
"prwords": prwords,
}
// Only known value of this field that works this way
if wordsRegion == "A" {
// TODO - The real server seems to handle the input words differently per region? These values are supposed to differ from prwords
reply["prwordsA"] = prwords
reply["prwordsC"] = prwords
reply["prwordsE"] = prwords
reply["prwordsJ"] = prwords
reply["prwordsK"] = prwords
reply["prwordsP"] = prwords
}
return reply
}
func dlsCount(fields map[string]string) string {