13d58139fSopenharmony_ci/* 23d58139fSopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. 33d58139fSopenharmony_ci * Licensed under Mulan PSL v2. 43d58139fSopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2. 53d58139fSopenharmony_ci * You may obtain a copy of Mulan PSL v2 at: 63d58139fSopenharmony_ci * http://license.coscl.org.cn/MulanPSL2 73d58139fSopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 83d58139fSopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 93d58139fSopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 103d58139fSopenharmony_ci * See the Mulan PSL v2 for more details. 113d58139fSopenharmony_ci * Description: vsnprintf_s function 123d58139fSopenharmony_ci * Create: 2014-02-25 133d58139fSopenharmony_ci */ 143d58139fSopenharmony_ci 153d58139fSopenharmony_ci#include "secureprintoutput.h" 163d58139fSopenharmony_ci 173d58139fSopenharmony_ci#if SECUREC_ENABLE_VSNPRINTF 183d58139fSopenharmony_ci/* 193d58139fSopenharmony_ci * <FUNCTION DESCRIPTION> 203d58139fSopenharmony_ci * The vsnprintf_s function is equivalent to the vsnprintf function 213d58139fSopenharmony_ci * except for the parameter destMax/count and the explicit runtime-constraints violation 223d58139fSopenharmony_ci * The vsnprintf_s function takes a pointer to an argument list, then formats 233d58139fSopenharmony_ci * and writes up to count characters of the given data to the memory pointed 243d58139fSopenharmony_ci * to by strDest and appends a terminating null. 253d58139fSopenharmony_ci * 263d58139fSopenharmony_ci * <INPUT PARAMETERS> 273d58139fSopenharmony_ci * strDest Storage location for the output. 283d58139fSopenharmony_ci * destMax The size of the strDest for output. 293d58139fSopenharmony_ci * count Maximum number of character to write(not including 303d58139fSopenharmony_ci * the terminating NULL) 313d58139fSopenharmony_ci * format Format-control string. 323d58139fSopenharmony_ci * argList pointer to list of arguments. 333d58139fSopenharmony_ci * 343d58139fSopenharmony_ci * <OUTPUT PARAMETERS> 353d58139fSopenharmony_ci * strDest is updated 363d58139fSopenharmony_ci * 373d58139fSopenharmony_ci * <RETURN VALUE> 383d58139fSopenharmony_ci * return the number of characters written, not including the terminating null 393d58139fSopenharmony_ci * return -1 if an error occurs. 403d58139fSopenharmony_ci * return -1 if count < destMax and the output string has been truncated 413d58139fSopenharmony_ci * 423d58139fSopenharmony_ci * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid 433d58139fSopenharmony_ci */ 443d58139fSopenharmony_ciint vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, va_list argList) 453d58139fSopenharmony_ci{ 463d58139fSopenharmony_ci int retVal; 473d58139fSopenharmony_ci 483d58139fSopenharmony_ci if (SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, SECUREC_STRING_MAX_LEN)) { 493d58139fSopenharmony_ci SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); 503d58139fSopenharmony_ci SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); 513d58139fSopenharmony_ci return -1; 523d58139fSopenharmony_ci } 533d58139fSopenharmony_ci 543d58139fSopenharmony_ci if (destMax > count) { 553d58139fSopenharmony_ci retVal = SecVsnprintfImpl(strDest, count + 1, format, argList); 563d58139fSopenharmony_ci if (retVal == SECUREC_PRINTF_TRUNCATE) { /* To keep dest buffer not destroyed 2014.2.18 */ 573d58139fSopenharmony_ci /* The string has been truncated, return -1 */ 583d58139fSopenharmony_ci return -1; /* To skip error handler, return strlen(strDest) or -1 */ 593d58139fSopenharmony_ci } 603d58139fSopenharmony_ci } else { 613d58139fSopenharmony_ci retVal = SecVsnprintfImpl(strDest, destMax, format, argList); 623d58139fSopenharmony_ci#ifdef SECUREC_COMPATIBLE_WIN_FORMAT 633d58139fSopenharmony_ci if (retVal == SECUREC_PRINTF_TRUNCATE && count == (size_t)(-1)) { 643d58139fSopenharmony_ci return -1; 653d58139fSopenharmony_ci } 663d58139fSopenharmony_ci#endif 673d58139fSopenharmony_ci } 683d58139fSopenharmony_ci 693d58139fSopenharmony_ci if (retVal < 0) { 703d58139fSopenharmony_ci strDest[0] = '\0'; /* Empty the dest strDest */ 713d58139fSopenharmony_ci if (retVal == SECUREC_PRINTF_TRUNCATE) { 723d58139fSopenharmony_ci /* Buffer too small */ 733d58139fSopenharmony_ci SECUREC_ERROR_INVALID_RANGE("vsnprintf_s"); 743d58139fSopenharmony_ci } 753d58139fSopenharmony_ci SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); 763d58139fSopenharmony_ci return -1; 773d58139fSopenharmony_ci } 783d58139fSopenharmony_ci 793d58139fSopenharmony_ci return retVal; 803d58139fSopenharmony_ci} 813d58139fSopenharmony_ci#if SECUREC_EXPORT_KERNEL_SYMBOL 823d58139fSopenharmony_ciEXPORT_SYMBOL(vsnprintf_s); 833d58139fSopenharmony_ci#endif 843d58139fSopenharmony_ci#endif 853d58139fSopenharmony_ci 863d58139fSopenharmony_ci#if SECUREC_SNPRINTF_TRUNCATED 873d58139fSopenharmony_ci/* 883d58139fSopenharmony_ci * <FUNCTION DESCRIPTION> 893d58139fSopenharmony_ci * The vsnprintf_truncated_s function is equivalent to the vsnprintf function 903d58139fSopenharmony_ci * except for the parameter destMax/count and the explicit runtime-constraints violation 913d58139fSopenharmony_ci * The vsnprintf_truncated_s function takes a pointer to an argument list, then formats 923d58139fSopenharmony_ci * and writes up to count characters of the given data to the memory pointed 933d58139fSopenharmony_ci * to by strDest and appends a terminating null. 943d58139fSopenharmony_ci * 953d58139fSopenharmony_ci * <INPUT PARAMETERS> 963d58139fSopenharmony_ci * strDest Storage location for the output. 973d58139fSopenharmony_ci * destMax The size of the strDest for output. 983d58139fSopenharmony_ci * the terminating NULL) 993d58139fSopenharmony_ci * format Format-control string. 1003d58139fSopenharmony_ci * argList pointer to list of arguments. 1013d58139fSopenharmony_ci * 1023d58139fSopenharmony_ci * <OUTPUT PARAMETERS> 1033d58139fSopenharmony_ci * strDest is updated 1043d58139fSopenharmony_ci * 1053d58139fSopenharmony_ci * <RETURN VALUE> 1063d58139fSopenharmony_ci * return the number of characters written, not including the terminating null 1073d58139fSopenharmony_ci * return -1 if an error occurs. 1083d58139fSopenharmony_ci * return destMax-1 if output string has been truncated 1093d58139fSopenharmony_ci * 1103d58139fSopenharmony_ci * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid 1113d58139fSopenharmony_ci */ 1123d58139fSopenharmony_ciint vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, va_list argList) 1133d58139fSopenharmony_ci{ 1143d58139fSopenharmony_ci int retVal; 1153d58139fSopenharmony_ci 1163d58139fSopenharmony_ci if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) { 1173d58139fSopenharmony_ci SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); 1183d58139fSopenharmony_ci SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s"); 1193d58139fSopenharmony_ci return -1; 1203d58139fSopenharmony_ci } 1213d58139fSopenharmony_ci 1223d58139fSopenharmony_ci retVal = SecVsnprintfImpl(strDest, destMax, format, argList); 1233d58139fSopenharmony_ci if (retVal < 0) { 1243d58139fSopenharmony_ci if (retVal == SECUREC_PRINTF_TRUNCATE) { 1253d58139fSopenharmony_ci return (int)(destMax - 1); /* To skip error handler, return strlen(strDest) */ 1263d58139fSopenharmony_ci } 1273d58139fSopenharmony_ci strDest[0] = '\0'; /* Empty the dest strDest */ 1283d58139fSopenharmony_ci SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s"); 1293d58139fSopenharmony_ci return -1; 1303d58139fSopenharmony_ci } 1313d58139fSopenharmony_ci 1323d58139fSopenharmony_ci return retVal; 1333d58139fSopenharmony_ci} 1343d58139fSopenharmony_ci#if SECUREC_EXPORT_KERNEL_SYMBOL 1353d58139fSopenharmony_ciEXPORT_SYMBOL(vsnprintf_truncated_s); 1363d58139fSopenharmony_ci#endif 1373d58139fSopenharmony_ci#endif 1383d58139fSopenharmony_ci 139