{"record":{"id":"16ff7a2776e56ee5","repo":"nodejs/node","slug":"u-buffer-overflow-error-16ff7a","errorCode":"U_BUFFER_OVERFLOW_ERROR","errorMessage":"icupkg/makeTargetName(%s) target item name length %ld too long\\n","messagePattern":"icupkg/makeTargetName\\((.+?)\\) target item name length %ld too long\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"deps/icu-small/source/tools/toolutil/pkgitems.cpp","lineNumber":152,"sourceCode":"    int32_t treeLength, suffixLength, targetLength;\n\n    // get the item basename\n    itemID=strrchr(itemName, '/');\n    if(itemID!=nullptr) {\n        ++itemID;\n    } else {\n        itemID=itemName;\n    }\n\n    // build the target string\n    treeLength = static_cast<int32_t>(itemID - itemName);\n    if(idLength<0) {\n        idLength = static_cast<int32_t>(strlen(id));\n    }\n    suffixLength = static_cast<int32_t>(strlen(suffix));\n    targetLength=treeLength+idLength+suffixLength;\n    if(targetLength>=capacity) {\n        fprintf(stderr, \"icupkg/makeTargetName(%s) target item name length %ld too long\\n\",\n                        itemName, static_cast<long>(targetLength));\n        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;\n        return;\n    }\n\n    memcpy(target, itemName, treeLength);\n    memcpy(target+treeLength, id, idLength);\n    memcpy(target+treeLength+idLength, suffix, suffixLength+1); // +1 includes the terminating NUL\n}\n\nstatic void \ncheckIDSuffix(const char *itemName, const char *id, int32_t idLength, const char *suffix,\n              CheckDependency check, void *context,\n              UErrorCode *pErrorCode) {\n    char target[200];\n    makeTargetName(itemName, id, idLength, suffix, target, static_cast<int32_t>(sizeof(target)), pErrorCode);\n    if(U_SUCCESS(*pErrorCode)) {\n        check(context, itemName, target);","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/icu-small/source/tools/toolutil/pkgitems.cpp#L134-L170","documentation":"makeTargetName composes target = treePart + id + suffix and checks the total against the caller's fixed-size buffer capacity; if targetLength >= capacity it prints the item name + length and sets *pErrorCode = U_BUFFER_OVERFLOW_ERROR (returns, does not exit). The capacity comes from sizeof() a local char[] at the call sites.","triggerScenarios":"An item whose name (tree path + id + suffix like .res) exceeds the stack buffer size passed in. The check `if(targetLength>=capacity)` fires before the memcpy block.","commonSituations":"A locale/resource path with many path components, or an unusually long locale ID, exceeding the fixed target buffer; a .dat containing pathologically named items.","solutions":["Shorten the item/locale names in the source data, or restructure the resource tree to be shallower.","Rebuild pkgitems with a larger target buffer at the call sites (sizeof target) if long names are legitimate.","Audit the .dat for items with unexpectedly long names (`icupkg -l`).","Validate name lengths before packaging and reject over-length entries upstream."],"exampleFix":"// before (pkgitems.cpp call site uses a fixed local buffer)\nchar target[256];\nmakeTargetName(itemName, id, idLen, \".res\", target, (int32_t)sizeof(target), &errorCode);\n// after\nchar target[1024];  // only if legitimately long names are required\nmakeTargetName(itemName, id, idLen, \".res\", target, (int32_t)sizeof(target), &errorCode);","handlingStrategy":"validation","validationCode":"// reject items whose composed target name would overflow a reasonable bound\nsize_t treeLen = strnlen(itemName, 256), idLen = idLength >= 0 ? (size_t)idLength : strlen(id), sufLen = strlen(suffix);\nif (treeLen + idLen + sufLen >= capacity) { *pErrorCode = U_BUFFER_OVERFLOW_ERROR; return; }","typeGuard":null,"tryCatchPattern":"// caller checks UErrorCode after makeTargetName (it sets the code, does not exit)\nUErrorCode err = U_ZERO_ERROR;\nmakeTargetName(itemName, id, idLen, suffix, target, (int32_t)sizeof(target), &err);\nif (U_FAILURE(err)) { /* log and skip this item; do not use target */ }","preventionTips":["Always check *pErrorCode after makeTargetName — it returns, it does not abort.","Keep resource/locale tree paths shallow and names reasonably short.","If long names are legitimate, enlarge the target buffer at the call site and rebuild.","Audit .dat contents with `icupkg -l` for pathologically named items."],"tags":["icu","icupkg","buffer-overflow","build-tools","data-validation"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}