1 /*-------------------------------------------------------------------------
2  *
3  * string.c
4  *		string handling helpers
5  *
6  *
7  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *	  src/common/string.c
13  *
14  *-------------------------------------------------------------------------
15  */
16 
17 
18 #ifndef FRONTEND
19 #include "postgres.h"
20 #else
21 #include "postgres_fe.h"
22 #endif
23 
24 #include "common/string.h"
25 
26 
27 /*
28  * Returns whether the string `str' has the postfix `end'.
29  */
30 bool
31 pg_str_endswith(const char *str, const char *end)
32 {
33 	size_t		slen = strlen(str);
34 	size_t		elen = strlen(end);
35 
36 	/* can't be a postfix if longer */
37 	if (elen > slen)
38 		return false;
39 
40 	/* compare the end of the strings */
41 	str += slen - elen;
42 	return strcmp(str, end) == 0;
43 }
44 
45 
46 /*
47  * strtoint --- just like strtol, but returns int not long
48  */
49 int
50 strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
51 {
52 	long		val;
53 
54 	val = strtol(str, endptr, base);
55 	if (val != (int) val)
56 		errno = ERANGE;
57 	return (int) val;
58 }
59 
60 
61 /*
62  * pg_clean_ascii -- Replace any non-ASCII chars with a '?' char
63  *
64  * Modifies the string passed in which must be '\0'-terminated.
65  *
66  * This function exists specifically to deal with filtering out
67  * non-ASCII characters in a few places where the client can provide an almost
68  * arbitrary string (and it isn't checked to ensure it's a valid username or
69  * database name or similar) and we don't want to have control characters or other
70  * things ending up in the log file where server admins might end up with a
71  * messed up terminal when looking at them.
72  *
73  * In general, this function should NOT be used- instead, consider how to handle
74  * the string without needing to filter out the non-ASCII characters.
75  *
76  * Ultimately, we'd like to improve the situation to not require stripping out
77  * all non-ASCII but perform more intelligent filtering which would allow UTF or
78  * similar, but it's unclear exactly what we should allow, so stick to ASCII only
79  * for now.
80  */
81 void
82 pg_clean_ascii(char *str)
83 {
84 	/* Only allow clean ASCII chars in the string */
85 	char	   *p;
86 
87 	for (p = str; *p != '\0'; p++)
88 	{
89 		if (*p < 32 || *p > 126)
90 			*p = '?';
91 	}
92 }
93 
94 
95 /*
96  * pg_strip_crlf -- Remove any trailing newline and carriage return
97  *
98  * Removes any trailing newline and carriage return characters (\r on
99  * Windows) in the input string, zero-terminating it.
100  *
101  * The passed in string must be zero-terminated.  This function returns
102  * the new length of the string.
103  */
104 int
105 pg_strip_crlf(char *str)
106 {
107 	int			len = strlen(str);
108 
109 	while (len > 0 && (str[len - 1] == '\n' ||
110 					   str[len - 1] == '\r'))
111 		str[--len] = '\0';
112 
113 	return len;
114 }
115