mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-10-10 04:53:09 +08:00
fix(drivers/189): decode JSON strings before parsing timestamps (#3033)
- Decode JSON time strings before normalizing Unicode spaces in both 189 drivers - Exercise escaped spaces and existing date formats through JSON unmarshalling - Cover invalid JSON input and XML time parsing Signed-off-by: jyxjjj <16695261+jyxjjj@users.noreply.github.com> Co-authored-by: Codex <267193182+codex@users.noreply.github.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
|||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -59,7 +60,13 @@ func timestamp() int64 {
|
|||||||
|
|
||||||
type Time time.Time
|
type Time time.Time
|
||||||
|
|
||||||
func (t *Time) UnmarshalJSON(b []byte) error { return t.Unmarshal(b) }
|
func (t *Time) UnmarshalJSON(b []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(b, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return t.Unmarshal([]byte(s))
|
||||||
|
}
|
||||||
func (t *Time) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) error {
|
func (t *Time) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) error {
|
||||||
b, err := e.Token()
|
b, err := e.Token()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package _189_tv
|
package _189_tv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -17,11 +19,13 @@ func TestTimeUnmarshal(t *testing.T) {
|
|||||||
{"new format no tz", `"Aug 11, 2026, 10:37:18 PM"`, time.Date(2026, 8, 11, 22, 37, 18, 0, time.FixedZone("", 8*3600))},
|
{"new format no tz", `"Aug 11, 2026, 10:37:18 PM"`, time.Date(2026, 8, 11, 22, 37, 18, 0, time.FixedZone("", 8*3600))},
|
||||||
{"narrow no-break space (U+202F)", "\"Aug 12, 2026, 12:35:41\u202fAM +08\"", time.Date(2026, 8, 12, 0, 35, 41, 0, time.FixedZone("", 8*3600))},
|
{"narrow no-break space (U+202F)", "\"Aug 12, 2026, 12:35:41\u202fAM +08\"", time.Date(2026, 8, 12, 0, 35, 41, 0, time.FixedZone("", 8*3600))},
|
||||||
{"no-break space (U+00A0)", "\"Aug 12, 2026, 12:35:41\u00a0AM +08\"", time.Date(2026, 8, 12, 0, 35, 41, 0, time.FixedZone("", 8*3600))},
|
{"no-break space (U+00A0)", "\"Aug 12, 2026, 12:35:41\u00a0AM +08\"", time.Date(2026, 8, 12, 0, 35, 41, 0, time.FixedZone("", 8*3600))},
|
||||||
|
{"JSON escaped narrow space", `"Sep 4, 2026, 10:59:33\u202fPM +08"`, time.Date(2026, 9, 4, 22, 59, 33, 0, time.FixedZone("", 8*3600))},
|
||||||
|
{"JSON escaped space without timezone", `"Sep 4, 2026, 12:59:33\u00a0AM"`, time.Date(2026, 9, 4, 0, 59, 33, 0, time.FixedZone("", 8*3600))},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
var tm Time
|
var tm Time
|
||||||
if err := tm.Unmarshal([]byte(tt.input)); err != nil {
|
if err := json.Unmarshal([]byte(tt.input), &tm); err != nil {
|
||||||
t.Fatalf("Unmarshal(%s) error: %v", tt.input, err)
|
t.Fatalf("Unmarshal(%s) error: %v", tt.input, err)
|
||||||
}
|
}
|
||||||
if !tt.want.Equal(time.Time(tm)) {
|
if !tt.want.Equal(time.Time(tm)) {
|
||||||
@@ -37,3 +41,25 @@ func TestTimeUnmarshalRejectsInvalid(t *testing.T) {
|
|||||||
t.Fatal("Unmarshal accepted an invalid time")
|
t.Fatal("Unmarshal accepted an invalid time")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTimeUnmarshalJSONRejectsInvalid(t *testing.T) {
|
||||||
|
for _, input := range []string{`"invalid"`, `123`, `null`, `"Sep 4, 2026, 10:59:33\uZZZZPM +08"`} {
|
||||||
|
t.Run(input, func(t *testing.T) {
|
||||||
|
var tm Time
|
||||||
|
if err := tm.UnmarshalJSON([]byte(input)); err == nil {
|
||||||
|
t.Fatalf("UnmarshalJSON(%s) accepted invalid input", input)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimeUnmarshalXML(t *testing.T) {
|
||||||
|
var tm Time
|
||||||
|
if err := xml.Unmarshal([]byte(`<time>Sep 4, 2026, 10:59:33 PM +08</time>`), &tm); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
want := time.Date(2026, 9, 4, 22, 59, 33, 0, time.FixedZone("", 8*3600))
|
||||||
|
if !want.Equal(time.Time(tm)) {
|
||||||
|
t.Fatalf("UnmarshalXML = %v, want %v", time.Time(tm), want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -102,7 +103,13 @@ func MustParseTime(str string) *time.Time {
|
|||||||
|
|
||||||
type Time time.Time
|
type Time time.Time
|
||||||
|
|
||||||
func (t *Time) UnmarshalJSON(b []byte) error { return t.Unmarshal(b) }
|
func (t *Time) UnmarshalJSON(b []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(b, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return t.Unmarshal([]byte(s))
|
||||||
|
}
|
||||||
func (t *Time) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) error {
|
func (t *Time) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) error {
|
||||||
b, err := e.Token()
|
b, err := e.Token()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package _189pc
|
package _189pc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -17,11 +19,13 @@ func TestTimeUnmarshal(t *testing.T) {
|
|||||||
{"new format no tz", `"Aug 11, 2026, 10:37:18 PM"`, time.Date(2026, 8, 11, 22, 37, 18, 0, time.FixedZone("", 8*3600))},
|
{"new format no tz", `"Aug 11, 2026, 10:37:18 PM"`, time.Date(2026, 8, 11, 22, 37, 18, 0, time.FixedZone("", 8*3600))},
|
||||||
{"narrow no-break space (U+202F)", "\"Aug 12, 2026, 12:35:41\u202fAM +08\"", time.Date(2026, 8, 12, 0, 35, 41, 0, time.FixedZone("", 8*3600))},
|
{"narrow no-break space (U+202F)", "\"Aug 12, 2026, 12:35:41\u202fAM +08\"", time.Date(2026, 8, 12, 0, 35, 41, 0, time.FixedZone("", 8*3600))},
|
||||||
{"no-break space (U+00A0)", "\"Aug 12, 2026, 12:35:41\u00a0AM +08\"", time.Date(2026, 8, 12, 0, 35, 41, 0, time.FixedZone("", 8*3600))},
|
{"no-break space (U+00A0)", "\"Aug 12, 2026, 12:35:41\u00a0AM +08\"", time.Date(2026, 8, 12, 0, 35, 41, 0, time.FixedZone("", 8*3600))},
|
||||||
|
{"JSON escaped narrow space", `"Sep 4, 2026, 10:59:33\u202fPM +08"`, time.Date(2026, 9, 4, 22, 59, 33, 0, time.FixedZone("", 8*3600))},
|
||||||
|
{"JSON escaped space without timezone", `"Sep 4, 2026, 12:59:33\u00a0AM"`, time.Date(2026, 9, 4, 0, 59, 33, 0, time.FixedZone("", 8*3600))},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
var tm Time
|
var tm Time
|
||||||
if err := tm.Unmarshal([]byte(tt.input)); err != nil {
|
if err := json.Unmarshal([]byte(tt.input), &tm); err != nil {
|
||||||
t.Fatalf("Unmarshal(%s) error: %v", tt.input, err)
|
t.Fatalf("Unmarshal(%s) error: %v", tt.input, err)
|
||||||
}
|
}
|
||||||
if !tt.want.Equal(time.Time(tm)) {
|
if !tt.want.Equal(time.Time(tm)) {
|
||||||
@@ -37,3 +41,25 @@ func TestTimeUnmarshalRejectsInvalid(t *testing.T) {
|
|||||||
t.Fatal("Unmarshal accepted an invalid time")
|
t.Fatal("Unmarshal accepted an invalid time")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTimeUnmarshalJSONRejectsInvalid(t *testing.T) {
|
||||||
|
for _, input := range []string{`"invalid"`, `123`, `null`, `"Sep 4, 2026, 10:59:33\uZZZZPM +08"`} {
|
||||||
|
t.Run(input, func(t *testing.T) {
|
||||||
|
var tm Time
|
||||||
|
if err := tm.UnmarshalJSON([]byte(input)); err == nil {
|
||||||
|
t.Fatalf("UnmarshalJSON(%s) accepted invalid input", input)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimeUnmarshalXML(t *testing.T) {
|
||||||
|
var tm Time
|
||||||
|
if err := xml.Unmarshal([]byte(`<time>Sep 4, 2026, 10:59:33 PM +08</time>`), &tm); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
want := time.Date(2026, 9, 4, 22, 59, 33, 0, time.FixedZone("", 8*3600))
|
||||||
|
if !want.Equal(time.Time(tm)) {
|
||||||
|
t.Fatalf("UnmarshalXML = %v, want %v", time.Time(tm), want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user