Hello.
Michael reports code below.
char buf[length];
strncpy(buf, p, length);
buf[length] = '\0’;
Last line write out of buf[] range.
So, I look for same bugs, and found some same type bugs.
One of same type bug has been fixed by debian patch.
I show others.
Please check codes.
Regards.
--
diff -rup ohcount-4.0.0.orig/src/detector.c ohcount-4.0.0/src/detector.c
--- ohcount-4.0.0.orig/src/detector.c 2019-02-27 05:39:28
+++ ohcount-4.0.0/src/detector.c 2025-06-17 21:23:08
@@ -44,7 +44,7 @@ const char *magic_parse(char *line) {
p += 4;
pe = p;
while (isalnum(*pe)) pe++;
- length = pe - p;
+ length = (pe - p < sizeof(buf)) ? pe - p : sizeof(buf)-1;
strncpy(buf, p, length);
buf[length] = '\0';
struct LanguageMap *rl = ohcount_hash_language_from_name(buf, length);
@@ -146,7 +146,7 @@ const char *ohcount_detect_language(SourceFile *source
while (pe < eof) {
// Get the contents of the first line.
while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
- length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
+ length = (pe - p < sizeof(line)) ? pe - p : sizeof(line)-1;
strncpy(line, p, length);
line[length] = '\0';
if (*line == '#' && *(line + 1) == '!') {
@@ -166,7 +166,7 @@ const char *ohcount_detect_language(SourceFile *source
}
pe = p;
while (!isspace(*pe) && *pe != ';' && pe != strstr(pe, "-*-")) pe++;
- length = (pe - p <= sizeof(buf)) ? pe - p : sizeof(buf);
+ length = (pe - p < sizeof(buf)) ? pe - p : sizeof(buf)-1;
strncpy(buf, p, length);
buf[length] = '\0';
@@ -236,7 +236,7 @@ const char *disambiguate_aspx(SourceFile *sourcefile)
if (p && pe) {
p += 3;
const int length = pe - p;
- char buf[length];
+ char buf[length+1];
strncpy(buf, p, length);
buf[length] = '\0';
char *eol = buf + strlen(buf);
@@ -323,7 +323,7 @@ const char *disambiguate_basic(SourceFile *sourcefile)
while (pe < eof) {
// Get a line at a time.
while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
- length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
+ length = (pe - p < sizeof(line)) ? pe - p : sizeof(line)-1;
strncpy(line, p, length);
line[length] = '\0';
char *line_end = pe;
@@ -550,7 +550,7 @@ const char *disambiguate_h(SourceFile *sourcefile) {
// If the directory contains a matching *.m file, likely Objective C.
length = strlen(sourcefile->filename);
if (strcmp(sourcefile->ext, "h") == 0) {
- char path[length];
+ char path[length+1];
strncpy(path, sourcefile->filename, length);
path[length] = '\0';
*(path + length - 1) = 'm';
@@ -572,7 +572,7 @@ const char *disambiguate_h(SourceFile *sourcefile) {
while (pe < eof) {
// Get a line at a time.
while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
- length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
+ length = (pe - p < sizeof(line)) ? pe - p : sizeof(line)-1;
strncpy(line, p, length);
line[length] = '\0';
char *eol = line + strlen(line);
@@ -592,7 +592,7 @@ const char *disambiguate_h(SourceFile *sourcefile) {
p++;
pe = p;
while (pe < eol && *pe != '>' && *pe != '"') pe++;
- length = pe - p;
+ length = (pe - p < sizeof(buf)) ? pe - p : sizeof(buf)-1;
strncpy(buf, p, length);
buf[length] = '\0';
if (ohcount_hash_is_cppheader(buf, length))
@@ -600,7 +600,7 @@ const char *disambiguate_h(SourceFile *sourcefile) {
// Is the extension for the header file a C++ file?
p = pe;
while (p > line && *(p - 1) != '.') p--;
- length = pe - p;
+ length = (pe - p < sizeof(buf)) ? pe - p : sizeof(buf)-1;
strncpy(buf, p, length);
buf[length] = '\0';
struct ExtensionMap *re = ohcount_hash_language_from_ext(buf,
length);
@@ -617,7 +617,7 @@ const char *disambiguate_h(SourceFile *sourcefile) {
pe = p;
while (islower(*pe)) pe++;
if (!isalnum(*pe) && *pe != '_') {
- length = pe - p;
+ length = (pe - p < sizeof(buf)) ? pe - p : sizeof(buf)-1;
strncpy(buf, p, length);
buf[length] = '\0';
if (strcmp(buf, "class") == 0 ||
@@ -650,7 +650,7 @@ const char *disambiguate_in(SourceFile *sourcefile) {
if (strstr(p, ".") <= pe) {
// Only if the filename has an extension prior to the .in
length = pe - p;
- char buf[length];
+ char buf[length+1];
strncpy(buf, p, length);
buf[length] = '\0';
p = ohcount_sourcefile_get_contents(sourcefile);
@@ -741,7 +741,7 @@ const char *disambiguate_m(SourceFile *sourcefile) {
while (pe < eof) {
// Get a line at a time.
while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
- length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
+ length = (pe - p < sizeof(line)) ? pe - p : sizeof(line)-1;
strncpy(line, p, length);
line[length] = '\0';
char *eol = line + strlen(line);
@@ -794,7 +794,7 @@ const char *disambiguate_m(SourceFile *sourcefile) {
pe = p;
while (islower(*pe) || *pe == '_') pe++;
if (!isalnum(*pe)) {
- length = pe - p;
+ length = (pe - p < sizeof(buf)) ? pe - p : sizeof(buf)-1;
strncpy(buf, p, length);
buf[length] = '\0';
if (strcmp(buf, "end_try_catch") == 0 ||
@@ -1029,7 +1029,7 @@ const char *disambiguate_st(SourceFile *sourcefile) {
while (pe < eof) {
// Get a line at a time.
while (pe < eof && *pe != '\r' && *pe != '\n') pe++;
- length = (pe - p <= sizeof(line)) ? pe - p : sizeof(line);
+ length = (pe - p < sizeof(line)) ? pe - p : sizeof(line)-1;
strncpy(line, p, length);
line[length] = '\0';
char *eol = line + strlen(line);
@@ -1066,7 +1066,7 @@ int ohcount_is_binary_filename(const char *filename) {
re = ohcount_hash_language_from_ext(p, length);
if (re) return ISBINARY(re->value);
// Try the lower-case version of this extension.
- char lowerext[length];
+ char lowerext[length+1];
strncpy(lowerext, p, length);
lowerext[length] = '\0';
for (p = lowerext; p < lowerext + length; p++) *p = tolower(*p);
diff -rup ohcount-4.0.0.orig/src/ohcount.c ohcount-4.0.0/src/ohcount.c
--- ohcount-4.0.0.orig/src/ohcount.c 2019-02-27 05:39:28
+++ ohcount-4.0.0/src/ohcount.c 2025-06-16 20:14:59
@@ -13,7 +13,7 @@ void annotate_callback(const char *language, const cha
int end, void *userdata) {
SourceFile *sf = (SourceFile *)userdata;
int length = end - start;
- char buf[length];
+ char buf[length+1];
strncpy(buf, (const char*)sf->contents + start, length); // field exists
buf[length] = '\0';
printf("%s\t%s\t%s", language, entity, buf);