{"record":{"id":"09b42b41df6c1262","repo":"redis/redis","slug":"out-of-memory","errorCode":null,"errorMessage":"Out of memory","messagePattern":"Out of memory","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"deps/lua/src/fpconv.c","lineNumber":129,"sourceCode":"    double value;\n\n    /* System strtod() is fine when decimal point is '.' */\n    if (locale_decimal_point == '.')\n        return strtod(nptr, endptr);\n\n    buflen = strtod_buffer_size(nptr);\n    if (!buflen) {\n        /* No valid characters found, standard strtod() return */\n        *endptr = (char *)nptr;\n        return 0;\n    }\n\n    /* Duplicate number into buffer */\n    if (buflen >= FPCONV_G_FMT_BUFSIZE) {\n        /* Handle unusually large numbers */\n        buf = malloc(buflen + 1);\n        if (!buf) {\n            fprintf(stderr, \"Out of memory\");\n            abort();\n        }\n    } else {\n        /* This is the common case.. */\n        buf = localbuf;\n    }\n    memcpy(buf, nptr, buflen);\n    buf[buflen] = 0;\n\n    /* Update decimal point character if found */\n    dp = strchr(buf, '.');\n    if (dp)\n        *dp = locale_decimal_point;\n\n    value = strtod(buf, &endbuf);\n    *endptr = (char *)&nptr[endbuf - buf];\n    if (buflen >= FPCONV_G_FMT_BUFSIZE)\n        free(buf);","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/redis/redis/blob/4f20cb48934463db5970bd476461b2d57af3f38d/deps/lua/src/fpconv.c#L111-L147","documentation":"Emitted by fpconv_strtod() then abort() when malloc() fails for an unusually large numeric token. This path only triggers for numbers longer than FPCONV_G_FMT_BUFSIZE that also use a non-dot locale decimal.","triggerScenarios":"At deps/lua/src/fpconv.c:127-130, when buflen >= FPCONV_G_FMT_BUFSIZE the code mallocs a buffer; if malloc returns NULL it prints 'Out of memory' and abort(). Requires both a non-'.' locale and an input number token spanning more than the stack buffer.","commonSituations":"Parsing JSON with pathologically long numeric literals under memory pressure while a comma-decimal locale is active; cjson fed untrusted huge-number input during OOM.","solutions":["Alleviate memory pressure (raise vm.overcommit / add RAM / reduce dataset).","Validate/reject absurdly long numeric tokens before passing JSON to cjson.","Run under LC_NUMERIC=C so the malloc path is never taken.","Cap the strtod_buffer_size and reject inputs above the cap before malloc."],"exampleFix":"// before\nif (buflen >= FPCONV_G_FMT_BUFSIZE) {\n    buf = malloc(buflen + 1);\n    if (!buf) { fprintf(stderr, \"Out of memory\"); abort(); }\n}\n// after\nif (buflen >= FPCONV_G_FMT_BUFSIZE) {\n    buf = malloc(buflen + 1);\n    if (!buf) { *endptr = (char *)nptr; return 0; }  /* degrade, do not abort */\n}","handlingStrategy":"validation","validationCode":"/* Reject absurdly long numeric tokens before handing JSON to cjson. */\nsize_t n = strspn(json, \"0123456789eE.+-aAbBcCdDfFpPxX\");\nif (n > 64) return JSON_PARSE_ERROR;   /* not a sane number */","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cap numeric token length before parsing to avoid the malloc path.","Run under LC_NUMERIC=C so fpconv_strtod uses system strtod and skips malloc.","Size memory headroom for the workload; monitor OOM conditions."],"tags":["c","lua","memory","oom","locale","abort","cjson"],"backgroundTag":null,"analyzedSha":"4f20cb48934463db5970bd476461b2d57af3f38d","analyzedAt":"2026-08-10T14:17:07.821Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}