1/* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. 3 * Licensed under Mulan PSL v2. 4 * You can use this software according to the terms and conditions of the Mulan PSL v2. 5 * You may obtain a copy of Mulan PSL v2 at: 6 * http://license.coscl.org.cn/MulanPSL2 7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 8 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 9 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 10 * See the Mulan PSL v2 for more details. 11 * Description: vsnprintf_s function 12 * Create: 2014-02-25 13 */ 14 15#include "secureprintoutput.h" 16 17#if SECUREC_ENABLE_VSNPRINTF 18/* 19 * <FUNCTION DESCRIPTION> 20 * The vsnprintf_s function is equivalent to the vsnprintf function 21 * except for the parameter destMax/count and the explicit runtime-constraints violation 22 * The vsnprintf_s function takes a pointer to an argument list, then formats 23 * and writes up to count characters of the given data to the memory pointed 24 * to by strDest and appends a terminating null. 25 * 26 * <INPUT PARAMETERS> 27 * strDest Storage location for the output. 28 * destMax The size of the strDest for output. 29 * count Maximum number of character to write(not including 30 * the terminating NULL) 31 * format Format-control string. 32 * argList pointer to list of arguments. 33 * 34 * <OUTPUT PARAMETERS> 35 * strDest is updated 36 * 37 * <RETURN VALUE> 38 * return the number of characters written, not including the terminating null 39 * return -1 if an error occurs. 40 * return -1 if count < destMax and the output string has been truncated 41 * 42 * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid 43 */ 44int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, va_list argList) 45{ 46 int retVal; 47 48 if (SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, SECUREC_STRING_MAX_LEN)) { 49 SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); 50 SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); 51 return -1; 52 } 53 54 if (destMax > count) { 55 retVal = SecVsnprintfImpl(strDest, count + 1, format, argList); 56 if (retVal == SECUREC_PRINTF_TRUNCATE) { /* To keep dest buffer not destroyed 2014.2.18 */ 57 /* The string has been truncated, return -1 */ 58 return -1; /* To skip error handler, return strlen(strDest) or -1 */ 59 } 60 } else { 61 retVal = SecVsnprintfImpl(strDest, destMax, format, argList); 62#ifdef SECUREC_COMPATIBLE_WIN_FORMAT 63 if (retVal == SECUREC_PRINTF_TRUNCATE && count == (size_t)(-1)) { 64 return -1; 65 } 66#endif 67 } 68 69 if (retVal < 0) { 70 strDest[0] = '\0'; /* Empty the dest strDest */ 71 if (retVal == SECUREC_PRINTF_TRUNCATE) { 72 /* Buffer too small */ 73 SECUREC_ERROR_INVALID_RANGE("vsnprintf_s"); 74 } 75 SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); 76 return -1; 77 } 78 79 return retVal; 80} 81#if SECUREC_EXPORT_KERNEL_SYMBOL 82EXPORT_SYMBOL(vsnprintf_s); 83#endif 84#endif 85 86#if SECUREC_SNPRINTF_TRUNCATED 87/* 88 * <FUNCTION DESCRIPTION> 89 * The vsnprintf_truncated_s function is equivalent to the vsnprintf function 90 * except for the parameter destMax/count and the explicit runtime-constraints violation 91 * The vsnprintf_truncated_s function takes a pointer to an argument list, then formats 92 * and writes up to count characters of the given data to the memory pointed 93 * to by strDest and appends a terminating null. 94 * 95 * <INPUT PARAMETERS> 96 * strDest Storage location for the output. 97 * destMax The size of the strDest for output. 98 * the terminating NULL) 99 * format Format-control string. 100 * argList pointer to list of arguments. 101 * 102 * <OUTPUT PARAMETERS> 103 * strDest is updated 104 * 105 * <RETURN VALUE> 106 * return the number of characters written, not including the terminating null 107 * return -1 if an error occurs. 108 * return destMax-1 if output string has been truncated 109 * 110 * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid 111 */ 112int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, va_list argList) 113{ 114 int retVal; 115 116 if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) { 117 SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); 118 SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s"); 119 return -1; 120 } 121 122 retVal = SecVsnprintfImpl(strDest, destMax, format, argList); 123 if (retVal < 0) { 124 if (retVal == SECUREC_PRINTF_TRUNCATE) { 125 return (int)(destMax - 1); /* To skip error handler, return strlen(strDest) */ 126 } 127 strDest[0] = '\0'; /* Empty the dest strDest */ 128 SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s"); 129 return -1; 130 } 131 132 return retVal; 133} 134#if SECUREC_EXPORT_KERNEL_SYMBOL 135EXPORT_SYMBOL(vsnprintf_truncated_s); 136#endif 137#endif 138 139