{"record":{"id":"ac6e6797575a3b82","repo":"kgretzky/evilginx2","slug":"you-can-only-use-time-duration-types-in-following","errorCode":null,"errorMessage":"you can only use time duration types in following order: 'd' > 'h' > 'm' > 's'","messagePattern":"you can only use time duration types in following order: 'd' > 'h' > 'm' > 's'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/utils.go","lineNumber":116,"sourceCode":"\t\t\t\t\tif m_index > last_type_index {\n\t\t\t\t\t\tlast_type_index = m_index\n\t\t\t\t\t\tvar val int64\n\t\t\t\t\t\tval, err = strconv.ParseInt(s_num, 10, 0)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tswitch c {\n\t\t\t\t\t\tcase 'd':\n\t\t\t\t\t\t\tdays = val\n\t\t\t\t\t\tcase 'h':\n\t\t\t\t\t\t\thours = val\n\t\t\t\t\t\tcase 'm':\n\t\t\t\t\t\t\tminutes = val\n\t\t\t\t\t\tcase 's':\n\t\t\t\t\t\t\tseconds = val\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\terr = fmt.Errorf(\"you can only use time duration types in following order: 'd' > 'h' > 'm' > 's'\")\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\terr = fmt.Errorf(\"unknown time duration type: '%s', you can use only 'd', 'h', 'm' or 's'\", string(c))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr = fmt.Errorf(\"time duration value needs to start with a number\")\n\t\t\t\treturn\n\t\t\t}\n\t\t\ts_num = \"\"\n\t\t}\n\t}\n\tt_dur = time.Duration(days)*24*time.Hour + time.Duration(hours)*time.Hour + time.Duration(minutes)*time.Minute + time.Duration(seconds)*time.Second\n\treturn\n}\n\nfunc GetDurationString(t_now time.Time, t_expire time.Time) (ret string) {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/kgretzky/evilginx2/blob/4c0988a1d9db4d172a185e979a38bfd0efdb5830/core/utils.go#L98-L134","documentation":"ParseDurationString parses custom duration strings like '5d12h30m' used for lure pause times. It enforces that unit characters appear in strictly descending order 'd' > 'h' > 'm' > 's'; if a unit character's index is not greater than the previous one (e.g. '30m5d' or '5h3h'), this error is returned and parsing stops.","triggerScenarios":"Passing a duration string whose units are out of order or repeated, e.g. '10s5m', '2h30m15h', '1d12d'.","commonSituations":"Users familiar with Go's time.ParseDuration writing '1h30s' (allowed by Go, rejected here because 's' after 'h' skips 'm' order is fine but '30s5h' is not), or typos reordering units.","solutions":["Rewrite the duration with units in order d, h, m, s, e.g. '1d12h30m15s'.","Remove duplicated units by summing them first: '5h3h' → '8h'.","Omit unwanted units entirely rather than reordering: '30m' instead of '30m0d'."],"exampleFix":"// before\nParseDurationString(\"30s5m\")\n// after\nParseDurationString(\"5m30s\")","handlingStrategy":"validation","validationCode":"var durRe = regexp.MustCompile(`^(?:\\d+d)?(?:\\d+h)?(?:\\d+m)?(?:\\d+s)?$`)\nif !durRe.MatchString(durStr) {\n    return fmt.Errorf(\"duration %q must use ordered units d>h>m>s, e.g. 1d12h30m\", durStr)\n}\nd, err := core.ParseDurationString(durStr)","typeGuard":"func isOrderedDuration(s string) bool {\n    last := -1\n    order := map[rune]int{'d': 0, 'h': 1, 'm': 2, 's': 3}\n    for _, c := range s {\n        if i, ok := order[c]; ok {\n            if i <= last { return false }\n            last = i\n        } else if c < '0' || c > '9' {\n            return false\n        }\n    }\n    return len(s) > 0\n}","tryCatchPattern":"d, err := core.ParseDurationString(input)\nif err != nil {\n    if strings.Contains(err.Error(), \"following order\") {\n        log.Printf(\"units out of order in %q; use d>h>m>s\", input)\n        return\n    }\n    return err\n}","preventionTips":["Always write units in descending order: d, h, m, s","Sum repeated units before formatting: 5h3h → 8h","Validate duration strings with a regex before calling ParseDurationString"],"tags":["parsing","duration","validation"],"backgroundTag":"invalid-duration-format","analyzedSha":"4c0988a1d9db4d172a185e979a38bfd0efdb5830","analyzedAt":"2026-09-05T19:23:07.238Z","contentChangedAt":"2026-09-05T19:23:07.238Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}