PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
string.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * string.c
4  * string handling helpers
5  *
6  *
7  * Portions Copyright (c) 1996-2024, 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 "\xXX" string
63  *
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.
68  *
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.
75  *
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.
78  *
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.
83  */
84 char *
85 pg_clean_ascii(const char *str, int alloc_flags)
86 {
87  size_t dstlen;
88  char *dst;
89  const char *p;
90  size_t i = 0;
91 
92  /* Worst case, each byte can become four bytes, plus a null terminator. */
93  dstlen = strlen(str) * 4 + 1;
94 
95 #ifdef FRONTEND
96  dst = malloc(dstlen);
97 #else
98  dst = palloc_extended(dstlen, alloc_flags);
99 #endif
100 
101  if (!dst)
102  return NULL;
103 
104  for (p = str; *p != '\0'; p++)
105  {
106 
107  /* Only allow clean ASCII chars in the string */
108  if (*p < 32 || *p > 126)
109  {
110  Assert(i < (dstlen - 3));
111  snprintf(&dst[i], dstlen - i, "\\x%02x", (unsigned char) *p);
112  i += 4;
113  }
114  else
115  {
116  Assert(i < dstlen);
117  dst[i] = *p;
118  i++;
119  }
120  }
121 
122  Assert(i < dstlen);
123  dst[i] = '\0';
124  return dst;
125 }
126 
127 
128 /*
129  * pg_is_ascii -- Check if string is made only of ASCII characters
130  */
131 bool
132 pg_is_ascii(const char *str)
133 {
134  while (*str)
135  {
136  if (IS_HIGHBIT_SET(*str))
137  return false;
138  str++;
139  }
140  return true;
141 }
142 
143 
144 /*
145  * pg_strip_crlf -- Remove any trailing newline and carriage return
146  *
147  * Removes any trailing newline and carriage return characters (\r on
148  * Windows) in the input string, zero-terminating it.
149  *
150  * The passed in string must be zero-terminated. This function returns
151  * the new length of the string.
152  */
153 int
155 {
156  int len = strlen(str);
157 
158  while (len > 0 && (str[len - 1] == '\n' ||
159  str[len - 1] == '\r'))
160  str[--len] = '\0';
161 
162  return len;
163 }
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1160
#define Assert(condition)
Definition: c.h:863
const char * str
#define malloc(a)
Definition: header.h:50
long val
Definition: informix.c:689
int i
Definition: isn.c:72
void * palloc_extended(Size size, int flags)
Definition: mcxt.c:1368
const void size_t len
#define snprintf
Definition: port.h:238
int pg_strip_crlf(char *str)
Definition: string.c:154
bool pg_is_ascii(const char *str)
Definition: string.c:132
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
Definition: string.c:50
bool pg_str_endswith(const char *str, const char *end)
Definition: string.c:31
char * pg_clean_ascii(const char *str, int alloc_flags)
Definition: string.c:85