1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: utnonansi - Non-ansi C library functions
5  *
6  ******************************************************************************/
7 
8 #include <acpi/acpi.h>
9 #include "accommon.h"
10 
11 #define _COMPONENT          ACPI_UTILITIES
12 ACPI_MODULE_NAME("utnonansi")
13 
14 /*
15  * Non-ANSI C library functions - strlwr, strupr, stricmp, and "safe"
16  * string functions.
17  */
18 /*******************************************************************************
19  *
20  * FUNCTION:    acpi_ut_strlwr (strlwr)
21  *
22  * PARAMETERS:  src_string      - The source string to convert
23  *
24  * RETURN:      None
25  *
26  * DESCRIPTION: Convert a string to lowercase
27  *
28  ******************************************************************************/
acpi_ut_strlwr(char * src_string)29 void acpi_ut_strlwr(char *src_string)
30 {
31 	char *string;
32 
33 	ACPI_FUNCTION_ENTRY();
34 
35 	if (!src_string) {
36 		return;
37 	}
38 
39 	/* Walk entire string, lowercasing the letters */
40 
41 	for (string = src_string; *string; string++) {
42 		*string = (char)tolower((int)*string);
43 	}
44 }
45 
46 /*******************************************************************************
47  *
48  * FUNCTION:    acpi_ut_strupr (strupr)
49  *
50  * PARAMETERS:  src_string      - The source string to convert
51  *
52  * RETURN:      None
53  *
54  * DESCRIPTION: Convert a string to uppercase
55  *
56  ******************************************************************************/
57 
acpi_ut_strupr(char * src_string)58 void acpi_ut_strupr(char *src_string)
59 {
60 	char *string;
61 
62 	ACPI_FUNCTION_ENTRY();
63 
64 	if (!src_string) {
65 		return;
66 	}
67 
68 	/* Walk entire string, uppercasing the letters */
69 
70 	for (string = src_string; *string; string++) {
71 		*string = (char)toupper((int)*string);
72 	}
73 }
74 
75 /******************************************************************************
76  *
77  * FUNCTION:    acpi_ut_stricmp (stricmp)
78  *
79  * PARAMETERS:  string1             - first string to compare
80  *              string2             - second string to compare
81  *
82  * RETURN:      int that signifies string relationship. Zero means strings
83  *              are equal.
84  *
85  * DESCRIPTION: Case-insensitive string compare. Implementation of the
86  *              non-ANSI stricmp function.
87  *
88  ******************************************************************************/
89 
acpi_ut_stricmp(char * string1,char * string2)90 int acpi_ut_stricmp(char *string1, char *string2)
91 {
92 	int c1;
93 	int c2;
94 
95 	do {
96 		c1 = tolower((int)*string1);
97 		c2 = tolower((int)*string2);
98 
99 		string1++;
100 		string2++;
101 	}
102 	while ((c1 == c2) && (c1));
103 
104 	return (c1 - c2);
105 }
106 
107 #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) || defined (ACPI_DEBUG_OUTPUT)
108 /*******************************************************************************
109  *
110  * FUNCTION:    acpi_ut_safe_strcpy, acpi_ut_safe_strcat, acpi_ut_safe_strncat
111  *
112  * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
113  *              functions. This is the size of the Destination buffer.
114  *
115  * RETURN:      TRUE if the operation would overflow the destination buffer.
116  *
117  * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
118  *              the result of the operation will not overflow the output string
119  *              buffer.
120  *
121  * NOTE:        These functions are typically only helpful for processing
122  *              user input and command lines. For most ACPICA code, the
123  *              required buffer length is precisely calculated before buffer
124  *              allocation, so the use of these functions is unnecessary.
125  *
126  ******************************************************************************/
127 
acpi_ut_safe_strcpy(char * dest,acpi_size dest_size,char * source)128 u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source)
129 {
130 
131 	if (strlen(source) >= dest_size) {
132 		return (TRUE);
133 	}
134 
135 	strcpy(dest, source);
136 	return (FALSE);
137 }
138 
acpi_ut_safe_strcat(char * dest,acpi_size dest_size,char * source)139 u8 acpi_ut_safe_strcat(char *dest, acpi_size dest_size, char *source)
140 {
141 
142 	if ((strlen(dest) + strlen(source)) >= dest_size) {
143 		return (TRUE);
144 	}
145 
146 	strcat(dest, source);
147 	return (FALSE);
148 }
149 
150 u8
acpi_ut_safe_strncat(char * dest,acpi_size dest_size,char * source,acpi_size max_transfer_length)151 acpi_ut_safe_strncat(char *dest,
152 		     acpi_size dest_size,
153 		     char *source, acpi_size max_transfer_length)
154 {
155 	acpi_size actual_transfer_length;
156 
157 	actual_transfer_length = ACPI_MIN(max_transfer_length, strlen(source));
158 
159 	if ((strlen(dest) + actual_transfer_length) >= dest_size) {
160 		return (TRUE);
161 	}
162 
163 	strncat(dest, source, max_transfer_length);
164 	return (FALSE);
165 }
166 
acpi_ut_safe_strncpy(char * dest,char * source,acpi_size dest_size)167 void acpi_ut_safe_strncpy(char *dest, char *source, acpi_size dest_size)
168 {
169 	/* Always terminate destination string */
170 
171 	strncpy(dest, source, dest_size);
172 	dest[dest_size - 1] = 0;
173 }
174 
175 #endif
176