본문 바로가기

프로그래밍/C

[library] strlcpy 구현하기

📌 매뉴얼 (Linux)

더보기

NAME
     strlcpy — size-bounded string copying

: size로 제한한 문자열 복사

 

SYNOPSIS
     #include <string.h>
     size_t strlcpy(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_strlcpy(char *dst, const char *src, size_t size)
{
	size_t	i;

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

 

📌 코드 리뷰

strlcpy는 dst에 src의 문자열을 복사해서 붙여주는 기능을 하는 함수이다. 따라서, while문을 통해서

인덱스인 i 로 반복문을 수행하는데, size 만큼 문자열을 붙이는게 아니라, null 문자가 마지막에 들어간다는 걸 생각해

size - 1 만큼 문자열이 복사되어야 한다. 그리하여 i < size - 1 의 조건을 주면 되는데, size는 size_t로 선언되어 있으므로,

마이너스 연산을 하면 문제가 될 가능성이 있다. (size_t는 unsigned int 와 마찬가지 이므로..)

따라서 -1을 이항하여, i + 1 < size 조건으로 바꿔주고, src[i]가 \0 이 아닌 조건도 추가해준다.

둘 중 하나라도 만족하지 않으면 반복문이 종료되어야 하므로, && 로 해주었다.

반복문 내에서는 dst[i]에 src[i]를 넣어주면서 해당 인덱스 위치의 값을 바꿔주는 동작을 수행하며, 인덱스인 i를 늘린다.

그리고 반복문이 종료되면 if문을 통해 마지막에 \0 문자를 추가해주는 과정이 있는데,

size가 0이면 \0 문자도 없는 빈문자열이 복사되어야 하므로 따로 조건에 size != 0 을 추가했다.

그리고 반환값은, 매뉴얼에서 확인할 수 있듯이 복사할 문자열인 src의 길이로 반환한다.

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

[library] strchr 구현하기  (0) 2024.03.30
[library] strlcat 구현하기  (2) 2024.03.19
[library] strlen 구현하기  (0) 2024.03.18
[library] isprint 구현하기  (0) 2024.03.18
[library] isascii 구현하기  (0) 2024.03.18
Recent Posts
Popular Posts
Recent Comments