Knowledge Base
Authentication is disabled (development mode).

string functions buffer size arguments

Edit

fgets fread readlink snprintf strcpyn strftime strncat strncpy strndup

char str[2];
strcpyn(sizeof(str), str, "XXX");           /* "X\0" */
strncpy(str, "XXX", sizeof(str) - 1);       /* "X?" */
snprintf(str, sizeof(str), "%s", "XXX");    /* "X\0" */
strncat(str, "XXX", sizeof(str) - 1);       /* "X\0" */
strndup("XXX", sizeof(str) - 1);            /* "X\0" */
fgets(str, sizeof(str), stdin);             /* "X\0" */
fread(str, 1, sizeof(str) - 1, stdin);      /* "X?" */
readlink("/tmp/XXX", str, sizeof(str) - 1); /* "X?" */
strftime(str, sizeof(str), "XXX", tm);      /* "X?" */

To test:

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

char str[2];

void hexdump(const char *str, size_t size)
{
	int i;
	int len;
	int pos;
	char hex[96];

	pos = 0;

	for (i = 0; i < size; i++)
	{
		len = snprintf(hex + pos, sizeof(hex) - pos, "%s%02x", i > 0 ? " " : "", str[i] & 0xff);

		if (len > 0)
			pos += len;
	}

	printf("%-54s", hex);

	for (i = 0; i < size; i++)
		printf("%c", isprint(str[i]) ? str[i] : '.');

	printf("\n");
}

static inline size_t strcpyn(size_t size, char *dst, const char *src)
{
	if (0 == size || NULL == dst || NULL == src)
	{
		size = 0;
	}
	else
	{
		size_t remain;

		remain = size;

		while (*src != '\0' && remain > sizeof((char)'\0'))
		{
			*dst++ = *src++;
			remain--;
		}

		size -= remain;
		*dst = '\0';
	}

	return size;
}

void test_strcpyn()
{
	strcpyn(sizeof(str), str, "XXX");
}

void test_strncpy()
{
	strncpy(str, "XXX", sizeof(str) - 1);
}

void test_snprintf()
{
	snprintf(str, sizeof(str), "%s", "XXX");
}

void test_strncat()
{
	str[0] = '\0';
	strncat(str, "XXX", sizeof(str) - 1);
}

void test_strndup()
{
	memcpy(str, strndup("XXX", sizeof(str) - 1), sizeof(str));
}

void test_fgets()
{
	fgets(str, sizeof(str), stdin);
}

void test_fread()
{
	fread(str, 1, sizeof(str) - 1, stdin);
}

void test_readlink()
{
	symlink("XXX", "/tmp/XXX");
	readlink("/tmp/XXX", str, sizeof(str) - 1);
}

void test_strftime()
{
	int len;
	time_t t;
	struct tm *tm;
	t = 0;
	tm = gmtime(&t);
	len = strftime(str, sizeof(str), "XXX", tm);
}

#define __str(x)	#x
#define test(fn)	\
	memset(str, 0xcc, sizeof(str)); \
	printf("%-16s: ", __str(fn)); \
	test_ ## fn (); \
	hexdump(str, sizeof(str))

int main(int argc, char *argv[])
{
	test(strcpyn);
	test(strncpy);
	test(snprintf);
	test(strncat);
	test(strndup);
	test(fgets);
	test(fread);
	test(readlink);
	test(strftime);

	return 0;
}