Is strlen invoked in snprintf calling this segfault?

I have void *, name it data, the length of which I know, but is not terminated by zero. I make such a call snprintf(line, sizeof(line), "%*s", n, (const char*)data), where nis the known length. It almost always works, but sometimes it leads to segfault.

Whenever segfault occurs, the backtrack says that the problem is inside strlen. And when I type datainside gdb, I see something like this

(gdb) p n
$1 = 88
(gdb) p (const char*) data
$2 = 0x1d752fa8
"JASDF" ... "ADS"<Address 0x1d753000 out of bounds>
(gdb) p 0x1d753000-0x1d752fa8
$3 = 88

dataindeed 88 characters, but not null, it actually seems to lie directly against the segment. I assume that snprintf is always called strlen on the data, and I was usually lucky that even if it was datanot null-terminated, before I hit the segment, there was \0, and then sometimes I was out of luck, and it is. It is right? If so, what kind of work?

This is what the stack trace looks like

#0  0x0000003c8927839e in strlen () from /lib64/libc.so.6
#1  0x0000003c89246749 in vfprintf () from /lib64/libc.so.6
#2  0x0000003c8926941a in vsnprintf () from /lib64/libc.so.6
#3  0x0000003c8924d0a3 in snprintf () from /lib64/libc.so.6

EDIT . To answer my own question about work, strncpy is a more suitable function to call. I used snprintf out of habit.

+3
source share
4 answers

snprintf(line, sizeof(line), "%*s", n, (const char*)data)

datadoesn't end with zero? Then you do it wrong.

snprintf(line, sizeof(line), "%.*s", n, (const char*)data);

.

* *.*, ( ) - - *. man printf .

, , %*s strlen(), , .

+7

, . , printf strlen, . , , C, %s, printf. Undefined.

+6

, . , strlen , \0. ( ), .

The solution is either that it ends with zero, or puts it in another buffer that you can disable.

+1
source

The workaround is to use memcpy():

size_t validlen = n < sizeof line ? n : (sizeof line - 1);
memcpy(line, data, validlen);
line[validlen] = '\0';
0
source

Source: https://habr.com/ru/post/1752547/


All Articles