본문 바로가기

프로그래밍/C

[library] strlcat 구현하기

📌 매뉴얼 (Linux)

더보기

NAME
     strlcat — size-bounded string concatenation

: size로 제한한 문자열 연결

 

SYNOPSIS
     #include <string.h>
     size_t strlcat(char *dst, const char *src, size_t size);

 

DESCRIPTION
     The strlcpy() and strlcat() functions copy and concatenate strings respectively.  They are de‐
     signed to be safer, more consistent, and less error prone replacements for strncpy(3) and
     strncat(3).  Unlike those functions, strlcpy() and strlcat() take the full size of the buffer
     (not just the length) and guarantee to NUL-terminate the result (as long as size is larger than
     0 or, in the case of strlcat(), as long as there is at least one byte free in dst).  Note that a
     byte for the NUL should be included in size.  Also note that strlcpy() and strlcat() only oper‐
     ate on true “C” strings.  This means that for strlcpy() src must be NUL-terminated and for
     strlcat() both src and dst must be NUL-terminated.

     The strlcpy() function copies up to size - 1 characters from the NUL-terminated string src to
     dst, NUL-terminating the result.

     The strlcat() function appends the NUL-terminated string src to the end of dst.  It will append
     at most size - strlen(dst) - 1 bytes, NUL-terminating the result.

: strlcpy() 및 strlcat() 기능은 각각 문자열을 복사하고 연결합니다. 이러한 기능은 strncpy(3) 및 strncat(3)에 대해 더 안전하고 일관성이 있으며 오류가 발생하기 쉬운 대체 기능으로 설계되었습니다. 이러한 기능과 달리 strlcpy() 및 strlcat()은 버퍼의 전체 크기(길이뿐만 아니라)를 가져와 NUL 종료 결과를 보장합니다(크기가 0보다 크다면 또는 strlcat()의 경우 dst에 하나 이상의 바이트 프리가 있으면). NUL용 바이트는 크기에 포함되어야 합니다. 또한 strlcpy() 및 strlcat()은 실제 "C" 문자열에서만 작동합니다. 이는 strlcpy()의 경우 src가 NUL 종료되어야 하며 strlcat()의 경우 src 및 dst 모두 NUL 종료되어야 함을 의미합니다.
strlcpy() 함수는 NUL 종단 문자열 src에서 dst로 최대 1자 크기까지 복사하여 NUL 종단 결과를 생성합니다.
strlcat() 함수는 NUL 종료 문자열 src를 dst의 끝에 추가합니다. 그것은 최대 크기 - strlen(dst) - 1 바이트, NUL 종료 결과를 추가합니다. (해석본)

 

RETURN VALUES
     The strlcpy() and strlcat() functions return the total length of the string they tried to cre‐
     ate.  For strlcpy() that means the length of src.  For strlcat() that means the initial length
     of dst plus the length of src.  While this may seem somewhat confusing, it was done to make
     truncation detection simple.

     Note, however, that if strlcat() traverses size characters without finding a NUL, the length of
     the string is considered to be size and the destination string will not be NUL-terminated (since
     there was no space for the NUL).  This keeps strlcat() from running off the end of a string.  In
     practice this should not happen (as it means that either size is incorrect or that dst is not a
     proper “C” string).  The check exists to prevent potential security problems in incorrect code.

: strlcpy()와 strlcat() 함수는 그들이 만들려고 했던 문자열의 전체 길이를 반환합니다. strlcpy()의 경우 src의 길이를 의미합니다. dst의 초기 길이에 src의 길이를 더한 것을 의미하는 strlcat()의 경우. 다소 혼란스러워 보일 수 있지만 절단 감지를 쉽게 하기 위해 수행되었습니다.
그러나 strlcat()이 NUL을 찾지 못하고 크기 문자를 통과하면 문자열의 길이는 크기로 간주되며 대상 문자열은 NUL로 종료되지 않습니다(NUL을 위한 공간이 없었기 때문). 이로 인해 strlcat()이 문자열 끝에서 실행되지 않습니다. 실제로는 이런 일이 발생해서는 안 됩니다(크기가 잘못되었거나 dst가 올바른 "C" 문자열이 아니기 때문). 이 검사는 잘못된 코드에서 발생할 수 있는 보안 문제를 방지하기 위해 존재합니다. (해석본)

 

📌 작성 코드

size_t	do_strlcat(char *dst, const char *src, size_t size)
{
	size_t	dst_len;
	size_t	src_len;
	size_t	i;

	if (size == 0 && dst == NULL)
		return (do_strlen(src));
	src_len = do_strlen(src);
	dst_len = do_strlen(dst);
	i = 0;
	if (dst_len >= size)
		return (src_len + size);
	while (i + dst_len + 1 < size && src[i] != '\0')
	{
		dst[dst_len + i] = src[i];
		i ++;
	}
	dst[dst_len + i] = '\0';
	return (src_len + dst_len);
}

 

📌 코드 리뷰

strlcat 은 size만큼 문자열을 연결시켜주는 함수이다. dst 뒤에 src를 붙여주는데, 여러 상황이 존재한다.

특히 반환값은, 두 문자열이 합쳐질 공간의 길이를 반환하는데, 이 반환값이 특이하게 나온다.

 

1) size가 0이거나 dst가 가리키는 문자열이 NULL인 경우, 동작을 수행하지 않고 src의 길이만 반환한다.

2) size 보다 dst의 길이가 크거나 같을 경우, 동작을 수행하지 않고 src 길이 + size를 반환한다.

3) size 보다 dst의 길이가 작은 경우, 반복문을 통해 src를 dst에 붙이는 동작을 수행한다.

4) src가 가리키는 문자열이 NULL인 경우, 반복문을 수행하지 않고, dst끝에 \0을 넣는 동작만 수행한다.

(3, 4 번 상황에서의 반환값은 src_len + dst_len 이다.)

 

우선 1번 상황은 size가 0이라서 붙이는 동작을 하지 않는 것이고, dst가 NULL이면 붙일 공간이 이미 문자열이 종료되어

붙이는 동작을 하지 않는다. 따라서, 반환값은 dst의 길이와 size를 제외한 src의 길이만 반환하게 된다.

2번 상황은, dst가 size보다 더 커서 붙이는 동작을 할 수 없는 상황이다. 따라서 size의 길이와 src 길이만 더해서

반환하면 합쳐질 공간의 길이가 반환된다고 볼 수 있다. 합쳐지지 않지만 합쳐졌을 때의 길이를 가정한다.

3번 상황은, 일반적인 상황인데, src를 붙이는 상황이 온 것이고, 이 때는 이제 size가 아닌 dst 길이를 넣어줘야

합쳐질 공간의 크기가 마련되어 반환하면 원하는 길이가 반환될 수 있다.

4번 상황에서는 단순히 3번 상황에서 src 내용이 없는 경우인데, dst가 그대로 나오고 반환도 결국 dst길이가 반환된다.

 

결론은, src가 하나라도 dst에 넣어지는 상황이 온다면, 반환값이 src길이 + dst길이로 바뀐다.

이 strlcat 함수는 'src의 길이를 항상 포함한 합쳐질 공간의 가능한 길이'를 반환한다고 보면 된다.

'프로그래밍 > C' 카테고리의 다른 글

[study] 가변인자 (variable argument)  (0) 2024.04.03
[library] strchr 구현하기  (0) 2024.03.30
[library] strlcpy 구현하기  (0) 2024.03.19
[library] strlen 구현하기  (0) 2024.03.18
[library] isprint 구현하기  (0) 2024.03.18
Recent Posts
Popular Posts
Recent Comments