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-2025, 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 */
30bool
31pg_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 */
49int
50strtoint(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 */
84char *
85pg_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 */
131bool
132pg_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 */
153int
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:1126
Assert(PointerIsAligned(start, uint64))
const char * str
#define malloc(a)
Definition: header.h:50
long val
Definition: informix.c:689
int i
Definition: isn.c:77
void * palloc_extended(Size size, int flags)
Definition: mcxt.c:1992
const void size_t len
#define snprintf
Definition: port.h:239
char * pg_clean_ascii(const char *str, int alloc_flags)
Definition: string.c:85
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