Repair memory leaks in plpython.
[pgsql.git] / src / common / string.c
blobd8a3129c3ba8d1338668e166c56b18848fa32a89
1 /*-------------------------------------------------------------------------
3 * string.c
4 * string handling helpers
7 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
11 * IDENTIFICATION
12 * src/common/string.c
14 *-------------------------------------------------------------------------
18 #ifndef FRONTEND
19 #include "postgres.h"
20 #else
21 #include "postgres_fe.h"
22 #endif
24 #include "common/string.h"
28 * Returns whether the string `str' has the postfix `end'.
30 bool
31 pg_str_endswith(const char *str, const char *end)
33 size_t slen = strlen(str);
34 size_t elen = strlen(end);
36 /* can't be a postfix if longer */
37 if (elen > slen)
38 return false;
40 /* compare the end of the strings */
41 str += slen - elen;
42 return strcmp(str, end) == 0;
47 * strtoint --- just like strtol, but returns int not long
49 int
50 strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
52 long val;
54 val = strtol(str, endptr, base);
55 if (val != (int) val)
56 errno = ERANGE;
57 return (int) val;
62 * pg_clean_ascii -- Replace any non-ASCII chars with a "\xXX" string
64 * Makes a newly allocated copy of the string passed in, which must be
65 * '\0'-terminated. In the backend, additional alloc_flags may be provided and
66 * will be passed as-is to palloc_extended(); in the frontend, alloc_flags is
67 * ignored and the copy is malloc'd.
69 * This function exists specifically to deal with filtering out
70 * non-ASCII characters in a few places where the client can provide an almost
71 * arbitrary string (and it isn't checked to ensure it's a valid username or
72 * database name or similar) and we don't want to have control characters or other
73 * things ending up in the log file where server admins might end up with a
74 * messed up terminal when looking at them.
76 * In general, this function should NOT be used- instead, consider how to handle
77 * the string without needing to filter out the non-ASCII characters.
79 * Ultimately, we'd like to improve the situation to not require replacing all
80 * non-ASCII but perform more intelligent filtering which would allow UTF or
81 * similar, but it's unclear exactly what we should allow, so stick to ASCII only
82 * for now.
84 char *
85 pg_clean_ascii(const char *str, int alloc_flags)
87 size_t dstlen;
88 char *dst;
89 const char *p;
90 size_t i = 0;
92 /* Worst case, each byte can become four bytes, plus a null terminator. */
93 dstlen = strlen(str) * 4 + 1;
95 #ifdef FRONTEND
96 dst = malloc(dstlen);
97 #else
98 dst = palloc_extended(dstlen, alloc_flags);
99 #endif
101 if (!dst)
102 return NULL;
104 for (p = str; *p != '\0'; p++)
107 /* Only allow clean ASCII chars in the string */
108 if (*p < 32 || *p > 126)
110 Assert(i < (dstlen - 3));
111 snprintf(&dst[i], dstlen - i, "\\x%02x", (unsigned char) *p);
112 i += 4;
114 else
116 Assert(i < dstlen);
117 dst[i] = *p;
118 i++;
122 Assert(i < dstlen);
123 dst[i] = '\0';
124 return dst;
129 * pg_is_ascii -- Check if string is made only of ASCII characters
131 bool
132 pg_is_ascii(const char *str)
134 while (*str)
136 if (IS_HIGHBIT_SET(*str))
137 return false;
138 str++;
140 return true;
145 * pg_strip_crlf -- Remove any trailing newline and carriage return
147 * Removes any trailing newline and carriage return characters (\r on
148 * Windows) in the input string, zero-terminating it.
150 * The passed in string must be zero-terminated. This function returns
151 * the new length of the string.
154 pg_strip_crlf(char *str)
156 int len = strlen(str);
158 while (len > 0 && (str[len - 1] == '\n' ||
159 str[len - 1] == '\r'))
160 str[--len] = '\0';
162 return len;