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 */
vsnprintf_s(char * strDest,size_t destMax,size_t count,const char * format,va_list argList)44 int 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
82 EXPORT_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 */
vsnprintf_truncated_s(char * strDest,size_t destMax,const char * format,va_list argList)112 int 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
135 EXPORT_SYMBOL(vsnprintf_truncated_s);
136 #endif
137 #endif
138
139