Error column is wrong when non-ASCII characters (é, emoji, ...) come earlier on the line: cppcheck counts bytes, Sublime counts characters
Version: SublimeLinter-cppcheck 3.x from Package Control, cppcheck 2.21.0, SublimeLinter 4, Sublime Text 4215. Reproduced in a clean install.
m.c (UTF-8, tab-indented):
#include <stdio.h>
int main(void) {
char buf[4];
printf("é😀"); buf[10] = 0;
int x = 5;
int *p = 0; *p = 1;
return 0;
}
Output of the command the linter runs (cppcheck --template={file}:{line}:{column}:{severity}:{id}:{message} --inline-suppr --quiet --enable=style --language=c m.c):
m.c:4:23:error:arrayIndexOutOfBounds:Array 'buf[4]' accessed at index 10, which is out of bounds.
m.c:6:15:error:nullPointer:Null pointer dereference: p
m.c:4:28:style:unreadVariable:Variable 'buf[10]' is assigned a value that is never used.
m.c:5:8:style:unreadVariable:Variable 'x' is assigned a value that is never used.
{column} is a byte offset into the UTF-8 line: é is 2 bytes and 😀 is 4, so on line 4 the [ of buf[10] is at byte column 23 but character column 19.
In Sublime the two errors on line 4 land in the wrong place (start offsets as SublimeLinter reports them, 0-based):
- arrayIndexOutOfBounds: start 22, which is the space after
buf[10], 4 characters too far to the right (expected 18, the [);
- unreadVariable: start 27, which is the newline at the end of the line, so the highlight is beyond the last character.
Lines 5 and 6 (ASCII only) are correct. Any accented letter in a string or comment before the error on the same line does this, so it will affect most non-English code bases.
Suggested fix: in reposition_match(self, line, col, m, vv) take the line with vv.select_line(line), and convert the byte column to a character column (encode the line to UTF-8, cut it at the byte offset, decode and take the length) before calling super(). That is the same approach as in SublimeLinter-xmllint, where a similar fix was merged today. I can prepare a PR if you would like one.
Error column is wrong when non-ASCII characters (é, emoji, ...) come earlier on the line: cppcheck counts bytes, Sublime counts characters
Version: SublimeLinter-cppcheck 3.x from Package Control, cppcheck 2.21.0, SublimeLinter 4, Sublime Text 4215. Reproduced in a clean install.
m.c(UTF-8, tab-indented):Output of the command the linter runs (
cppcheck --template={file}:{line}:{column}:{severity}:{id}:{message} --inline-suppr --quiet --enable=style --language=c m.c):{column}is a byte offset into the UTF-8 line:éis 2 bytes and😀is 4, so on line 4 the[ofbuf[10]is at byte column 23 but character column 19.In Sublime the two errors on line 4 land in the wrong place (start offsets as SublimeLinter reports them, 0-based):
buf[10], 4 characters too far to the right (expected 18, the[);Lines 5 and 6 (ASCII only) are correct. Any accented letter in a string or comment before the error on the same line does this, so it will affect most non-English code bases.
Suggested fix: in
reposition_match(self, line, col, m, vv)take the line withvv.select_line(line), and convert the byte column to a character column (encode the line to UTF-8, cut it at the byte offset, decode and take the length) before callingsuper(). That is the same approach as in SublimeLinter-xmllint, where a similar fix was merged today. I can prepare a PR if you would like one.