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