strlcat.c (5293B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#include <CUnit/CUnit.h> 21#include <guacamole/string.h> 22 23#include <stdlib.h> 24#include <string.h> 25 26/** 27 * Verify guac_strlcat() behavior when the string fits the buffer without 28 * truncation. The return value of each call should be the length of the 29 * resulting string. Each resulting string should contain the full result of 30 * the concatenation, including null terminator. 31 */ 32void test_string__strlcat() { 33 34 char buffer[1024]; 35 36 memset(buffer, 0xFF, sizeof(buffer)); 37 strcpy(buffer, "Apache "); 38 CU_ASSERT_EQUAL(guac_strlcat(buffer, "Guacamole", sizeof(buffer)), 16); 39 CU_ASSERT_STRING_EQUAL(buffer, "Apache Guacamole"); 40 CU_ASSERT_EQUAL(buffer[17], '\xFF'); 41 42 memset(buffer, 0xFF, sizeof(buffer)); 43 strcpy(buffer, ""); 44 CU_ASSERT_EQUAL(guac_strlcat(buffer, "This is a test", sizeof(buffer)), 14); 45 CU_ASSERT_STRING_EQUAL(buffer, "This is a test"); 46 CU_ASSERT_EQUAL(buffer[15], '\xFF'); 47 48 memset(buffer, 0xFF, sizeof(buffer)); 49 strcpy(buffer, "AB"); 50 CU_ASSERT_EQUAL(guac_strlcat(buffer, "X", sizeof(buffer)), 3); 51 CU_ASSERT_STRING_EQUAL(buffer, "ABX"); 52 CU_ASSERT_EQUAL(buffer[4], '\xFF'); 53 54 memset(buffer, 0xFF, sizeof(buffer)); 55 strcpy(buffer, "X"); 56 CU_ASSERT_EQUAL(guac_strlcat(buffer, "", sizeof(buffer)), 1); 57 CU_ASSERT_STRING_EQUAL(buffer, "X"); 58 CU_ASSERT_EQUAL(buffer[2], '\xFF'); 59 60 memset(buffer, 0xFF, sizeof(buffer)); 61 strcpy(buffer, ""); 62 CU_ASSERT_EQUAL(guac_strlcat(buffer, "", sizeof(buffer)), 0); 63 CU_ASSERT_STRING_EQUAL(buffer, ""); 64 CU_ASSERT_EQUAL(buffer[1], '\xFF'); 65 66} 67 68/** 69 * Verify guac_strlcat() behavior when the string must be truncated to fit the 70 * buffer. The return value of each call should be the length that would result 71 * from concatenating the strings given an infinite buffer, however only as 72 * many characters as can fit should be appended to the string within the 73 * buffer, and the buffer should be null-terminated. 74 */ 75void test_string__strlcat_truncate() { 76 77 char buffer[1024]; 78 79 memset(buffer, 0xFF, sizeof(buffer)); 80 strcpy(buffer, "Apache "); 81 CU_ASSERT_EQUAL(guac_strlcat(buffer, "Guacamole", 9), 16); 82 CU_ASSERT_STRING_EQUAL(buffer, "Apache G"); 83 CU_ASSERT_EQUAL(buffer[9], '\xFF'); 84 85 memset(buffer, 0xFF, sizeof(buffer)); 86 strcpy(buffer, ""); 87 CU_ASSERT_EQUAL(guac_strlcat(buffer, "This is a test", 10), 14); 88 CU_ASSERT_STRING_EQUAL(buffer, "This is a"); 89 CU_ASSERT_EQUAL(buffer[10], '\xFF'); 90 91 memset(buffer, 0xFF, sizeof(buffer)); 92 strcpy(buffer, "This "); 93 CU_ASSERT_EQUAL(guac_strlcat(buffer, "is ANOTHER test", 6), 20); 94 CU_ASSERT_STRING_EQUAL(buffer, "This "); 95 CU_ASSERT_EQUAL(buffer[6], '\xFF'); 96 97} 98 99/** 100 * Verify guac_strlcat() behavior with zero buffer sizes. The return value of 101 * each call should be the size of the input string, while the buffer remains 102 * untouched. 103 */ 104void test_string__strlcat_nospace() { 105 106 /* 0-byte buffer plus 1 guard byte (to test overrun) */ 107 char buffer[1] = { '\xFF' }; 108 109 CU_ASSERT_EQUAL(guac_strlcat(buffer, "Guacamole", 0), 9); 110 CU_ASSERT_EQUAL(buffer[0], '\xFF'); 111 112 CU_ASSERT_EQUAL(guac_strlcat(buffer, "This is a test", 0), 14); 113 CU_ASSERT_EQUAL(buffer[0], '\xFF'); 114 115 CU_ASSERT_EQUAL(guac_strlcat(buffer, "X", 0), 1); 116 CU_ASSERT_EQUAL(buffer[0], '\xFF'); 117 118 CU_ASSERT_EQUAL(guac_strlcat(buffer, "", 0), 0); 119 CU_ASSERT_EQUAL(buffer[0], '\xFF'); 120 121} 122 123/** 124 * Verify guac_strlcat() behavior with unterminated buffers. With respect to 125 * the return value, the length of the string in the buffer should be 126 * considered equal to the size of the buffer, however the resulting buffer 127 * should not be null-terminated. 128 */ 129void test_string__strlcat_nonull() { 130 131 char expected[1024]; 132 memset(expected, 0xFF, sizeof(expected)); 133 134 char buffer[1024]; 135 136 memset(buffer, 0xFF, sizeof(buffer)); 137 CU_ASSERT_EQUAL(guac_strlcat(buffer, "Guacamole", 256), 265); 138 CU_ASSERT_NSTRING_EQUAL(buffer, expected, sizeof(expected)); 139 140 memset(buffer, 0xFF, sizeof(buffer)); 141 CU_ASSERT_EQUAL(guac_strlcat(buffer, "This is a test", 37), 51); 142 CU_ASSERT_NSTRING_EQUAL(buffer, expected, sizeof(expected)); 143 144 memset(buffer, 0xFF, sizeof(buffer)); 145 CU_ASSERT_EQUAL(guac_strlcat(buffer, "X", 12), 13); 146 CU_ASSERT_NSTRING_EQUAL(buffer, expected, sizeof(expected)); 147 148 memset(buffer, 0xFF, sizeof(buffer)); 149 CU_ASSERT_EQUAL(guac_strlcat(buffer, "", 100), 100); 150 CU_ASSERT_NSTRING_EQUAL(buffer, expected, sizeof(expected)); 151 152} 153