CWE-135 is the incorrect calculation of the length of strings that can contain wide or multi-byte characters. The root cause is a simple mismatch. One part of the code counts characters, another counts bytes, and the buffer is sized with the wrong one.
MITRE lists C and C++ as the affected languages. It matters for anything that handles Unicode, wide character APIs, or text in encodings like UTF-8 and UTF-16.
How it happens
In a single-byte encoding, one character is one byte, and strlen is the answer. With wide characters, one character may occupy two or four bytes. In UTF-8, one character takes between one and four bytes. The same text has different lengths depending on the unit.
// Vulnerable: wchar_t is 2 or 4 bytes, but the size counts characters
wchar_t *copy_wide(const wchar_t *src) {
size_t n = wcslen(src); // characters
wchar_t *dst = malloc(n + 1); // bytes, too small by a factor of 2 or 4
wcscpy(dst, src);
return dst;
}
The allocation is measured in bytes, but n + 1 is a count of characters. The copy then writes several times more data than the buffer holds.
// Fixed: multiply by the element size
wchar_t *copy_wide(const wchar_t *src) {
size_t n = wcslen(src) + 1;
if (n > SIZE_MAX / sizeof(wchar_t)) return NULL;
wchar_t *dst = malloc(n * sizeof(wchar_t));
if (!dst) return NULL;
wmemcpy(dst, src, n);
return dst;
}
The reverse mistake also happens: a bounds check made in characters but applied to a buffer measured in bytes, or a conversion from a wide string to UTF-8 where the output buffer was sized as if each character became one byte.
What an attacker gains
MITRE lists three consequences.
- Code execution. The weakness may lead to a buffer overflow. Overflows can often be used to execute arbitrary code outside the product's implicit security policy.
- Crashes and resource use. Out-of-bounds memory access can corrupt relevant memory, and perhaps instructions, possibly leading to a crash.
- Memory disclosure. An out-of-bounds read can expose sensitive information, including details such as the current position of the buffer in memory, which helps craft further attacks.
How to find it
MITRE names automated static analysis, which can find some instances by analyzing source code without running it. Practical additions:
- Test with non-ASCII input in every text field. Use two-byte, three-byte and four-byte UTF-8 sequences, not just accented Latin letters.
- Search for allocations next to
wcslen,mbstowcsandwcstombsand check that the units agree. - Run those tests with AddressSanitizer so a size mismatch fails the test.
How to fix it
The record lists no mitigations. These steps follow from the definition.
- Decide on a unit for every length variable and name it, for example
len_bytesandlen_chars. - Multiply by
sizeofthe element type when allocating for wide strings. - Use the conversion functions' size query mode to learn how many bytes the output needs before allocating.
- Prefer string types that manage their own size.
- Validate encoding on input so malformed sequences are rejected early.
Quick check
Why does ASCII-only testing miss this bug?
With ASCII, characters and bytes are the same count, so the two lengths agree. The mismatch only appears when input includes wide or multi-byte characters.