Decode: add missing checks for LocalTime (#650)

This commit is contained in:
Thomas Pelletier
2021-10-29 22:13:08 -04:00
committed by GitHub
parent 772d169b52
commit 85c0658984
2 changed files with 68 additions and 11 deletions
+39 -10
View File
@@ -35,13 +35,22 @@ func parseLocalDate(b []byte) (LocalDate, error) {
return date, newDecodeError(b, "dates are expected to have the format YYYY-MM-DD")
}
date.Year = parseDecimalDigits(b[0:4])
var err error
v := parseDecimalDigits(b[5:7])
date.Year, err = parseDecimalDigits(b[0:4])
if err != nil {
return LocalDate{}, err
}
date.Month = v
date.Month, err = parseDecimalDigits(b[5:7])
if err != nil {
return LocalDate{}, err
}
date.Day = parseDecimalDigits(b[8:10])
date.Day, err = parseDecimalDigits(b[8:10])
if err != nil {
return LocalDate{}, err
}
if !isValidDate(date.Year, date.Month, date.Day) {
return LocalDate{}, newDecodeError(b, "impossible date")
@@ -50,15 +59,18 @@ func parseLocalDate(b []byte) (LocalDate, error) {
return date, nil
}
func parseDecimalDigits(b []byte) int {
func parseDecimalDigits(b []byte) (int, error) {
v := 0
for _, c := range b {
for i, c := range b {
if c < '0' || c > '9' {
return 0, newDecodeError(b[i:i+1], "expected digit (0-9)")
}
v *= 10
v += int(c - '0')
}
return v
return v, nil
}
func parseDateTime(b []byte) (time.Time, error) {
@@ -159,7 +171,13 @@ func parseLocalTime(b []byte) (LocalTime, []byte, error) {
return t, nil, newDecodeError(b, "times are expected to have the format HH:MM:SS[.NNNNNN]")
}
t.Hour = parseDecimalDigits(b[0:2])
var err error
t.Hour, err = parseDecimalDigits(b[0:2])
if err != nil {
return t, nil, err
}
if t.Hour > 23 {
return t, nil, newDecodeError(b[0:2], "hour cannot be greater 23")
}
@@ -167,7 +185,10 @@ func parseLocalTime(b []byte) (LocalTime, []byte, error) {
return t, nil, newDecodeError(b[2:3], "expecting colon between hours and minutes")
}
t.Minute = parseDecimalDigits(b[3:5])
t.Minute, err = parseDecimalDigits(b[3:5])
if err != nil {
return t, nil, err
}
if t.Minute > 59 {
return t, nil, newDecodeError(b[3:5], "minutes cannot be greater 59")
}
@@ -175,7 +196,11 @@ func parseLocalTime(b []byte) (LocalTime, []byte, error) {
return t, nil, newDecodeError(b[5:6], "expecting colon between minutes and seconds")
}
t.Second = parseDecimalDigits(b[6:8])
t.Second, err = parseDecimalDigits(b[6:8])
if err != nil {
return t, nil, err
}
if t.Second > 59 {
return t, nil, newDecodeError(b[3:5], "seconds cannot be greater 59")
}
@@ -204,6 +229,10 @@ func parseLocalTime(b []byte) (LocalTime, []byte, error) {
digits++
}
if digits == 0 {
return t, nil, newDecodeError(b[minLengthWithFrac-1:minLengthWithFrac], "nanoseconds need at least one digit")
}
t.Nanosecond = frac * nspow[digits]
t.Precision = digits
+29 -1
View File
@@ -2002,7 +2002,7 @@ world'`,
{
desc: "invalid minutes value",
data: `a=1979-05-27T23:+2:99`,
msg: `minutes cannot be greater 59`,
msg: `expected digit (0-9)`,
},
{
desc: "invalid seconds value",
@@ -2183,6 +2183,34 @@ world'`,
data: `A = 2021-02-29T23:59:00`,
msg: `impossible date`,
},
{
desc: `missing minute digit`,
data: `a=17:4::01`,
},
{
desc: `invalid space in year`,
data: `i=19 7-12-21T10:32:00`,
},
{
desc: `missing nanoseconds digits`,
data: `a=17:45:56.`,
},
{
desc: `minutes over 60`,
data: `a=17:99:00`,
},
{
desc: `invalid second`,
data: `a=17:00::0`,
},
{
desc: `invalid hour`,
data: `a=1::00:00`,
},
{
desc: `invalid month`,
data: `a=2021-0--29`,
},
}
for _, e := range examples {