summaryrefslogtreecommitdiff
path: root/vendor/github.com/pelletier/go-toml/v2/decode.go
diff options
context:
space:
mode:
authorLibravatar Terin Stock <terinjokes@gmail.com>2025-03-09 17:47:56 +0100
committerLibravatar Terin Stock <terinjokes@gmail.com>2025-03-10 01:59:49 +0100
commit3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch)
treef61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/pelletier/go-toml/v2/decode.go
parent[chore] update URLs to forked source (diff)
downloadgotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/pelletier/go-toml/v2/decode.go')
-rw-r--r--vendor/github.com/pelletier/go-toml/v2/decode.go550
1 files changed, 0 insertions, 550 deletions
diff --git a/vendor/github.com/pelletier/go-toml/v2/decode.go b/vendor/github.com/pelletier/go-toml/v2/decode.go
deleted file mode 100644
index f0ec3b170..000000000
--- a/vendor/github.com/pelletier/go-toml/v2/decode.go
+++ /dev/null
@@ -1,550 +0,0 @@
-package toml
-
-import (
- "fmt"
- "math"
- "strconv"
- "time"
-
- "github.com/pelletier/go-toml/v2/unstable"
-)
-
-func parseInteger(b []byte) (int64, error) {
- if len(b) > 2 && b[0] == '0' {
- switch b[1] {
- case 'x':
- return parseIntHex(b)
- case 'b':
- return parseIntBin(b)
- case 'o':
- return parseIntOct(b)
- default:
- panic(fmt.Errorf("invalid base '%c', should have been checked by scanIntOrFloat", b[1]))
- }
- }
-
- return parseIntDec(b)
-}
-
-func parseLocalDate(b []byte) (LocalDate, error) {
- // full-date = date-fullyear "-" date-month "-" date-mday
- // date-fullyear = 4DIGIT
- // date-month = 2DIGIT ; 01-12
- // date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on month/year
- var date LocalDate
-
- if len(b) != 10 || b[4] != '-' || b[7] != '-' {
- return date, unstable.NewParserError(b, "dates are expected to have the format YYYY-MM-DD")
- }
-
- var err error
-
- date.Year, err = parseDecimalDigits(b[0:4])
- if err != nil {
- return LocalDate{}, err
- }
-
- date.Month, err = parseDecimalDigits(b[5:7])
- if err != nil {
- return LocalDate{}, err
- }
-
- date.Day, err = parseDecimalDigits(b[8:10])
- if err != nil {
- return LocalDate{}, err
- }
-
- if !isValidDate(date.Year, date.Month, date.Day) {
- return LocalDate{}, unstable.NewParserError(b, "impossible date")
- }
-
- return date, nil
-}
-
-func parseDecimalDigits(b []byte) (int, error) {
- v := 0
-
- for i, c := range b {
- if c < '0' || c > '9' {
- return 0, unstable.NewParserError(b[i:i+1], "expected digit (0-9)")
- }
- v *= 10
- v += int(c - '0')
- }
-
- return v, nil
-}
-
-func parseDateTime(b []byte) (time.Time, error) {
- // offset-date-time = full-date time-delim full-time
- // full-time = partial-time time-offset
- // time-offset = "Z" / time-numoffset
- // time-numoffset = ( "+" / "-" ) time-hour ":" time-minute
-
- dt, b, err := parseLocalDateTime(b)
- if err != nil {
- return time.Time{}, err
- }
-
- var zone *time.Location
-
- if len(b) == 0 {
- // parser should have checked that when assigning the date time node
- panic("date time should have a timezone")
- }
-
- if b[0] == 'Z' || b[0] == 'z' {
- b = b[1:]
- zone = time.UTC
- } else {
- const dateTimeByteLen = 6
- if len(b) != dateTimeByteLen {
- return time.Time{}, unstable.NewParserError(b, "invalid date-time timezone")
- }
- var direction int
- switch b[0] {
- case '-':
- direction = -1
- case '+':
- direction = +1
- default:
- return time.Time{}, unstable.NewParserError(b[:1], "invalid timezone offset character")
- }
-
- if b[3] != ':' {
- return time.Time{}, unstable.NewParserError(b[3:4], "expected a : separator")
- }
-
- hours, err := parseDecimalDigits(b[1:3])
- if err != nil {
- return time.Time{}, err
- }
- if hours > 23 {
- return time.Time{}, unstable.NewParserError(b[:1], "invalid timezone offset hours")
- }
-
- minutes, err := parseDecimalDigits(b[4:6])
- if err != nil {
- return time.Time{}, err
- }
- if minutes > 59 {
- return time.Time{}, unstable.NewParserError(b[:1], "invalid timezone offset minutes")
- }
-
- seconds := direction * (hours*3600 + minutes*60)
- if seconds == 0 {
- zone = time.UTC
- } else {
- zone = time.FixedZone("", seconds)
- }
- b = b[dateTimeByteLen:]
- }
-
- if len(b) > 0 {
- return time.Time{}, unstable.NewParserError(b, "extra bytes at the end of the timezone")
- }
-
- t := time.Date(
- dt.Year,
- time.Month(dt.Month),
- dt.Day,
- dt.Hour,
- dt.Minute,
- dt.Second,
- dt.Nanosecond,
- zone)
-
- return t, nil
-}
-
-func parseLocalDateTime(b []byte) (LocalDateTime, []byte, error) {
- var dt LocalDateTime
-
- const localDateTimeByteMinLen = 11
- if len(b) < localDateTimeByteMinLen {
- return dt, nil, unstable.NewParserError(b, "local datetimes are expected to have the format YYYY-MM-DDTHH:MM:SS[.NNNNNNNNN]")
- }
-
- date, err := parseLocalDate(b[:10])
- if err != nil {
- return dt, nil, err
- }
- dt.LocalDate = date
-
- sep := b[10]
- if sep != 'T' && sep != ' ' && sep != 't' {
- return dt, nil, unstable.NewParserError(b[10:11], "datetime separator is expected to be T or a space")
- }
-
- t, rest, err := parseLocalTime(b[11:])
- if err != nil {
- return dt, nil, err
- }
- dt.LocalTime = t
-
- return dt, rest, nil
-}
-
-// parseLocalTime is a bit different because it also returns the remaining
-// []byte that is didn't need. This is to allow parseDateTime to parse those
-// remaining bytes as a timezone.
-func parseLocalTime(b []byte) (LocalTime, []byte, error) {
- var (
- nspow = [10]int{0, 1e8, 1e7, 1e6, 1e5, 1e4, 1e3, 1e2, 1e1, 1e0}
- t LocalTime
- )
-
- // check if b matches to have expected format HH:MM:SS[.NNNNNN]
- const localTimeByteLen = 8
- if len(b) < localTimeByteLen {
- return t, nil, unstable.NewParserError(b, "times are expected to have the format HH:MM:SS[.NNNNNN]")
- }
-
- var err error
-
- t.Hour, err = parseDecimalDigits(b[0:2])
- if err != nil {
- return t, nil, err
- }
-
- if t.Hour > 23 {
- return t, nil, unstable.NewParserError(b[0:2], "hour cannot be greater 23")
- }
- if b[2] != ':' {
- return t, nil, unstable.NewParserError(b[2:3], "expecting colon between hours and minutes")
- }
-
- t.Minute, err = parseDecimalDigits(b[3:5])
- if err != nil {
- return t, nil, err
- }
- if t.Minute > 59 {
- return t, nil, unstable.NewParserError(b[3:5], "minutes cannot be greater 59")
- }
- if b[5] != ':' {
- return t, nil, unstable.NewParserError(b[5:6], "expecting colon between minutes and seconds")
- }
-
- t.Second, err = parseDecimalDigits(b[6:8])
- if err != nil {
- return t, nil, err
- }
-
- if t.Second > 60 {
- return t, nil, unstable.NewParserError(b[6:8], "seconds cannot be greater 60")
- }
-
- b = b[8:]
-
- if len(b) >= 1 && b[0] == '.' {
- frac := 0
- precision := 0
- digits := 0
-
- for i, c := range b[1:] {
- if !isDigit(c) {
- if i == 0 {
- return t, nil, unstable.NewParserError(b[0:1], "need at least one digit after fraction point")
- }
- break
- }
- digits++
-
- const maxFracPrecision = 9
- if i >= maxFracPrecision {
- // go-toml allows decoding fractional seconds
- // beyond the supported precision of 9
- // digits. It truncates the fractional component
- // to the supported precision and ignores the
- // remaining digits.
- //
- // https://github.com/pelletier/go-toml/discussions/707
- continue
- }
-
- frac *= 10
- frac += int(c - '0')
- precision++
- }
-
- if precision == 0 {
- return t, nil, unstable.NewParserError(b[:1], "nanoseconds need at least one digit")
- }
-
- t.Nanosecond = frac * nspow[precision]
- t.Precision = precision
-
- return t, b[1+digits:], nil
- }
- return t, b, nil
-}
-
-//nolint:cyclop
-func parseFloat(b []byte) (float64, error) {
- if len(b) == 4 && (b[0] == '+' || b[0] == '-') && b[1] == 'n' && b[2] == 'a' && b[3] == 'n' {
- return math.NaN(), nil
- }
-
- cleaned, err := checkAndRemoveUnderscoresFloats(b)
- if err != nil {
- return 0, err
- }
-
- if cleaned[0] == '.' {
- return 0, unstable.NewParserError(b, "float cannot start with a dot")
- }
-
- if cleaned[len(cleaned)-1] == '.' {
- return 0, unstable.NewParserError(b, "float cannot end with a dot")
- }
-
- dotAlreadySeen := false
- for i, c := range cleaned {
- if c == '.' {
- if dotAlreadySeen {
- return 0, unstable.NewParserError(b[i:i+1], "float can have at most one decimal point")
- }
- if !isDigit(cleaned[i-1]) {
- return 0, unstable.NewParserError(b[i-1:i+1], "float decimal point must be preceded by a digit")
- }
- if !isDigit(cleaned[i+1]) {
- return 0, unstable.NewParserError(b[i:i+2], "float decimal point must be followed by a digit")
- }
- dotAlreadySeen = true
- }
- }
-
- start := 0
- if cleaned[0] == '+' || cleaned[0] == '-' {
- start = 1
- }
- if cleaned[start] == '0' && len(cleaned) > start+1 && isDigit(cleaned[start+1]) {
- return 0, unstable.NewParserError(b, "float integer part cannot have leading zeroes")
- }
-
- f, err := strconv.ParseFloat(string(cleaned), 64)
- if err != nil {
- return 0, unstable.NewParserError(b, "unable to parse float: %w", err)
- }
-
- return f, nil
-}
-
-func parseIntHex(b []byte) (int64, error) {
- cleaned, err := checkAndRemoveUnderscoresIntegers(b[2:])
- if err != nil {
- return 0, err
- }
-
- i, err := strconv.ParseInt(string(cleaned), 16, 64)
- if err != nil {
- return 0, unstable.NewParserError(b, "couldn't parse hexadecimal number: %w", err)
- }
-
- return i, nil
-}
-
-func parseIntOct(b []byte) (int64, error) {
- cleaned, err := checkAndRemoveUnderscoresIntegers(b[2:])
- if err != nil {
- return 0, err
- }
-
- i, err := strconv.ParseInt(string(cleaned), 8, 64)
- if err != nil {
- return 0, unstable.NewParserError(b, "couldn't parse octal number: %w", err)
- }
-
- return i, nil
-}
-
-func parseIntBin(b []byte) (int64, error) {
- cleaned, err := checkAndRemoveUnderscoresIntegers(b[2:])
- if err != nil {
- return 0, err
- }
-
- i, err := strconv.ParseInt(string(cleaned), 2, 64)
- if err != nil {
- return 0, unstable.NewParserError(b, "couldn't parse binary number: %w", err)
- }
-
- return i, nil
-}
-
-func isSign(b byte) bool {
- return b == '+' || b == '-'
-}
-
-func parseIntDec(b []byte) (int64, error) {
- cleaned, err := checkAndRemoveUnderscoresIntegers(b)
- if err != nil {
- return 0, err
- }
-
- startIdx := 0
-
- if isSign(cleaned[0]) {
- startIdx++
- }
-
- if len(cleaned) > startIdx+1 && cleaned[startIdx] == '0' {
- return 0, unstable.NewParserError(b, "leading zero not allowed on decimal number")
- }
-
- i, err := strconv.ParseInt(string(cleaned), 10, 64)
- if err != nil {
- return 0, unstable.NewParserError(b, "couldn't parse decimal number: %w", err)
- }
-
- return i, nil
-}
-
-func checkAndRemoveUnderscoresIntegers(b []byte) ([]byte, error) {
- start := 0
- if b[start] == '+' || b[start] == '-' {
- start++
- }
-
- if len(b) == start {
- return b, nil
- }
-
- if b[start] == '_' {
- return nil, unstable.NewParserError(b[start:start+1], "number cannot start with underscore")
- }
-
- if b[len(b)-1] == '_' {
- return nil, unstable.NewParserError(b[len(b)-1:], "number cannot end with underscore")
- }
-
- // fast path
- i := 0
- for ; i < len(b); i++ {
- if b[i] == '_' {
- break
- }
- }
- if i == len(b) {
- return b, nil
- }
-
- before := false
- cleaned := make([]byte, i, len(b))
- copy(cleaned, b)
-
- for i++; i < len(b); i++ {
- c := b[i]
- if c == '_' {
- if !before {
- return nil, unstable.NewParserError(b[i-1:i+1], "number must have at least one digit between underscores")
- }
- before = false
- } else {
- before = true
- cleaned = append(cleaned, c)
- }
- }
-
- return cleaned, nil
-}
-
-func checkAndRemoveUnderscoresFloats(b []byte) ([]byte, error) {
- if b[0] == '_' {
- return nil, unstable.NewParserError(b[0:1], "number cannot start with underscore")
- }
-
- if b[len(b)-1] == '_' {
- return nil, unstable.NewParserError(b[len(b)-1:], "number cannot end with underscore")
- }
-
- // fast path
- i := 0
- for ; i < len(b); i++ {
- if b[i] == '_' {
- break
- }
- }
- if i == len(b) {
- return b, nil
- }
-
- before := false
- cleaned := make([]byte, 0, len(b))
-
- for i := 0; i < len(b); i++ {
- c := b[i]
-
- switch c {
- case '_':
- if !before {
- return nil, unstable.NewParserError(b[i-1:i+1], "number must have at least one digit between underscores")
- }
- if i < len(b)-1 && (b[i+1] == 'e' || b[i+1] == 'E') {
- return nil, unstable.NewParserError(b[i+1:i+2], "cannot have underscore before exponent")
- }
- before = false
- case '+', '-':
- // signed exponents
- cleaned = append(cleaned, c)
- before = false
- case 'e', 'E':
- if i < len(b)-1 && b[i+1] == '_' {
- return nil, unstable.NewParserError(b[i+1:i+2], "cannot have underscore after exponent")
- }
- cleaned = append(cleaned, c)
- case '.':
- if i < len(b)-1 && b[i+1] == '_' {
- return nil, unstable.NewParserError(b[i+1:i+2], "cannot have underscore after decimal point")
- }
- if i > 0 && b[i-1] == '_' {
- return nil, unstable.NewParserError(b[i-1:i], "cannot have underscore before decimal point")
- }
- cleaned = append(cleaned, c)
- default:
- before = true
- cleaned = append(cleaned, c)
- }
- }
-
- return cleaned, nil
-}
-
-// isValidDate checks if a provided date is a date that exists.
-func isValidDate(year int, month int, day int) bool {
- return month > 0 && month < 13 && day > 0 && day <= daysIn(month, year)
-}
-
-// daysBefore[m] counts the number of days in a non-leap year
-// before month m begins. There is an entry for m=12, counting
-// the number of days before January of next year (365).
-var daysBefore = [...]int32{
- 0,
- 31,
- 31 + 28,
- 31 + 28 + 31,
- 31 + 28 + 31 + 30,
- 31 + 28 + 31 + 30 + 31,
- 31 + 28 + 31 + 30 + 31 + 30,
- 31 + 28 + 31 + 30 + 31 + 30 + 31,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
-}
-
-func daysIn(m int, year int) int {
- if m == 2 && isLeap(year) {
- return 29
- }
- return int(daysBefore[m] - daysBefore[m-1])
-}
-
-func isLeap(year int) bool {
- return year%4 == 0 && (year%100 != 0 || year%400 == 0)
-}
-
-func isDigit(r byte) bool {
- return r >= '0' && r <= '9'
-}