{"id":3896,"date":"2019-12-21T00:01:56","date_gmt":"2019-12-21T08:01:56","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=3896"},"modified":"2019-12-14T10:23:39","modified_gmt":"2019-12-14T18:23:39","slug":"decoding-the-strlcat-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3896","title":{"rendered":"Decoding the <em>strlcat()<\/em> Function"},"content":{"rendered":"<p>The <em>strlcat()<\/em> function (with the L) achieves the same goal as the venerable <em>strcat()<\/em> function: to append one string onto the end of the other. The problem with <em>strcat()<\/em>, however, is that a size limitation isn&#8217;t set for the destination buffer. It&#8217;s quite possible for this buffer to overflow.<br \/>\n<!--more--><br \/>\nAs a solution, the <em>strlcat()<\/em> function offers an additional argument, <code>dstsize<\/code>. This argument sets the length of the destination string, effectively equal to its buffer size. Here&#8217;s the function&#8217;s prototype:<\/p>\n<p><code>size_t strlcat(char * restrict dst, const char * restrict src, size_t dstsize);<\/code><\/p>\n<p>Characters from string <code>src<\/code> are appended to string <code>dst<\/code>. The <code>dstsize<\/code> argument is equal to the size of the <code>dst<\/code> buffer, which caps the number of characters copied to this size, minus one for the null character. Here&#8217;s the awkward way the <em>man<\/em> page puts it:<\/p>\n<blockquote><p><strong>strlcat()<\/strong> appends string src to the end of <span style=\"text-decoration:underline\">dst<\/span>.  It will append at most <span style=\"text-decoration:underline\">dstsize<\/span> &#8211; strlen(dst) &#8211; 1 characters.  It will then NUL-terminate, unless <span style=\"text-decoration:underline\">dstsize<\/span> is 0 or the original <span style=\"text-decoration:underline\">dst<\/span> string was longer than <span style=\"text-decoration:underline\">dstsize<\/span> (in practice this should not happen as it means that either <span style=\"text-decoration:underline\">dstsize<\/span> is incorrect or that <span style=\"text-decoration:underline\">dst<\/span> is not a proper string).<\/p><\/blockquote>\n<p>Ugh. Again, argument <code>dstsize<\/code> must be equal to the size of the <code>dst<\/code> buffer. That&#8217;s the only value it can be.<\/p>\n<p>The <em>strlcat()<\/em> function returns the combined length of both <code>src<\/code> and <code>dst<\/code> strings (not counting their terminating null characters). This result is used to determine whether the final string was truncated. Here&#8217;s sample code:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\nint main()\r\n{\r\n    char first[] = \"This is \";\r\n    char last[] = \"a potentially long string\";\r\n    int r;\r\n    int size = 16;\r\n    char buffer[size];\r\n\r\n    strcpy(buffer,first);\r\n    r = strlcat(buffer,last,size);\r\n\r\n    puts(buffer);\r\n    printf(\"Value returned: %d\\n\",r);\r\n    if( r &gt; size )\r\n        puts(\"String truncated\");\r\n    else\r\n        puts(\"String was fully copied\");\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>strlcat()<\/em> function at Line 13 appends string <code>last<\/code> to string <code>first<\/code>, which has been copied into <em>char<\/em> array <code>buffer[]<\/code>. The size of the <code>buffer[]<\/code> array is set to 16, which is too short to accommodate the entire <code>last<\/code> string. Yet, because the same value, 16, is specified in the <em>strlcat()<\/em> function, a buffer overflow doesn&#8217;t occur.<\/p>\n<p>A test is made at Line 17 comparing values <code>r<\/code> (returned from <em>strlcat()<\/em>) and <code>size<\/code> to determine whether the string was truncated.<\/p>\n<p>Here&#8217;s sample output:<\/p>\n<p><code>This is a poten<br \/>\nValue returned: 33<br \/>\nString truncated<\/code><\/p>\n<p>The value returned (33) is equal to the size of both original strings, <code>first<\/code> and <code>last<\/code>. It&#8217;s the <em>strlen()<\/em> value, not the strings&#8217; size in memory, which would include two more bytes for the two null characters at the end of each string.<\/p>\n<p>If you modify Line 9 to change the <code>size<\/code> variable (and buffer size) to 64, the buffer is now large enough to accommodate the concatenated strings. Here&#8217;s the updated output:<\/p>\n<p><code>This is a potentially long string<br \/>\nValue returned: 33<br \/>\nString was fully copied<\/code><\/p>\n<p>Armed with all this data, it becomes a simpler task for me to craft my own, substitute <em>strlcat()<\/em> function. I present this solution in next week&#8217;s Lesson.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The <em>strlcat()<\/em> function&#8217;s return values must be deciphered before I attempt to code my own version. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3896\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-3896","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3896","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3896"}],"version-history":[{"count":6,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3896\/revisions"}],"predecessor-version":[{"id":3911,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3896\/revisions\/3911"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3896"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3896"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3896"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}