{"record":{"id":"5167a462a85ca23b","repo":"valyala/fasthttp","slug":"negative-input-is-invalid","errorCode":null,"errorMessage":"negative input is invalid","messagePattern":"negative input is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bytesconv.go","lineNumber":359,"sourceCode":"\t\t\treturn 0, parsed, errUnexpectedTrailingChar\n\t\t}\n\t\tparsed = parsed*10 + int(k)\n\t\tif octet > 25 || (octet == 25 && k > 5) {\n\t\t\treturn 0, parsed, errIPv4PartTooLarge\n\t\t}\n\t\toctet = octet*10 + k\n\t}\n\treturn octet, parsed, nil\n}\n\n// ParseUfloat parses unsigned float from buf.\nfunc ParseUfloat(buf []byte) (float64, error) {\n\t// The implementation of parsing a float string is not easy.\n\t// We believe that the conservative approach is to call strconv.ParseFloat.\n\t// https://github.com/valyala/fasthttp/pull/1865\n\tres, err := strconv.ParseFloat(b2s(buf), 64)\n\tif res < 0 {\n\t\treturn -1, errors.New(\"negative input is invalid\")\n\t}\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\treturn res, err\n}\n\nvar (\n\terrEmptyHexNum    = errors.New(\"empty hex number\")\n\terrTooLargeHexNum = errors.New(\"too large hex number\")\n)\n\nfunc readHexInt(r *bufio.Reader) (int, error) {\n\tvar k, i, n int\n\tfor {\n\t\tc, err := r.ReadByte()\n\t\tif err != nil {\n\t\t\tif err == io.EOF && i > 0 {","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/bytesconv.go#L341-L377","documentation":"ParseUfloat parses an unsigned float from a byte slice via strconv.ParseFloat, then rejects results below zero with an ad-hoc errors.New(\"negative input is invalid\"). It is raised inside ParseUfloat itself (not a declared sentinel), so callers must match on the message or pre-validate. Note the check runs before err is examined, so a negative result triggers this even on parse warnings.","triggerScenarios":"ParseUfloat([]byte(\"-1.5\")) or args.GetUfloat on a value like ?price=-3.2 — any input whose parsed float is negative.","commonSituations":"Client sending negative values for quantities that must be non-negative (prices, percentages, weights); sign typos ('-0.5' instead of '0.5'); signed sensors/offsets fed to an unsigned parser.","solutions":["Validate the first byte is not '-' before calling ParseUfloat and give the user a clear message.","Catch the error and compare err.Error() == \"negative input is invalid\" to branch on this specific case, since no sentinel is exported.","If negative values are legitimate, use strconv.ParseFloat(string(buf), 64) directly instead of ParseUfloat.","Return 400 for user input, or clamp negatives to 0 if the domain allows it."],"exampleFix":"// before\nv, err := fasthttp.ParseUfloat(b) // \"negative input is invalid\"\n// after\nif len(b) > 0 && b[0] == '-' {\n    return 0, errors.New(\"value must be non-negative\")\n}\nv, err := fasthttp.ParseUfloat(b)","handlingStrategy":"validation","validationCode":"func parseUfloatNonNeg(b []byte) (float64, error) {\n    if len(b) > 0 && b[0] == '-' {\n        return 0, errors.New(\"value must be non-negative\")\n    }\n    return fasthttp.ParseUfloat(b)\n}","typeGuard":"func isNonNegativeNumber(b []byte) bool {\n    return len(b) > 0 && b[0] != '-'\n}","tryCatchPattern":"v, err := fasthttp.ParseUfloat(b)\nif err != nil {\n    if err.Error() == \"negative input is invalid\" {\n        return 0, errors.New(\"negative values are not allowed here\")\n    }\n    return err\n}","preventionTips":["Check for a leading '-' before unsigned parsing","Clamp negatives to 0 when the domain permits","Use strconv.ParseFloat directly when signs are valid input","Return 400 with a field-specific message for user input"],"tags":["float-parsing","input-validation","negative-value"],"backgroundTag":"negative-number-rejected","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}