LCOV - code coverage report
Current view: top level - src/common - string.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 69.8 % 53 37
Test Date: 2026-01-26 10:56:24 Functions: 80.0 % 5 4
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 60.7 % 28 17

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * string.c
       4                 :             :  *              string handling helpers
       5                 :             :  *
       6                 :             :  *
       7                 :             :  * Portions Copyright (c) 1996-2026, 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                 :           0 : pg_str_endswith(const char *str, const char *end)
      32                 :             : {
      33                 :           0 :         size_t          slen = strlen(str);
      34                 :           0 :         size_t          elen = strlen(end);
      35                 :             : 
      36                 :             :         /* can't be a postfix if longer */
      37         [ #  # ]:           0 :         if (elen > slen)
      38                 :           0 :                 return false;
      39                 :             : 
      40                 :             :         /* compare the end of the strings */
      41                 :           0 :         str += slen - elen;
      42                 :           0 :         return strcmp(str, end) == 0;
      43                 :           0 : }
      44                 :             : 
      45                 :             : 
      46                 :             : /*
      47                 :             :  * strtoint --- just like strtol, but returns int not long
      48                 :             :  */
      49                 :             : int
      50                 :       10978 : strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
      51                 :             : {
      52                 :       10978 :         long            val;
      53                 :             : 
      54                 :       10978 :         val = strtol(str, endptr, base);
      55         [ +  - ]:       10978 :         if (val != (int) val)
      56                 :           0 :                 errno = ERANGE;
      57                 :       21956 :         return (int) val;
      58                 :       10978 : }
      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                 :        1120 : pg_clean_ascii(const char *str, int alloc_flags)
      86                 :             : {
      87                 :        1120 :         size_t          dstlen;
      88                 :        1120 :         char       *dst;
      89                 :        1120 :         const char *p;
      90                 :        1120 :         size_t          i = 0;
      91                 :             : 
      92                 :             :         /* Worst case, each byte can become four bytes, plus a null terminator. */
      93                 :        1120 :         dstlen = strlen(str) * 4 + 1;
      94                 :             : 
      95                 :             : #ifdef FRONTEND
      96                 :           0 :         dst = malloc(dstlen);
      97                 :             : #else
      98                 :        1120 :         dst = palloc_extended(dstlen, alloc_flags);
      99                 :             : #endif
     100                 :             : 
     101         [ +  - ]:        1120 :         if (!dst)
     102                 :           0 :                 return NULL;
     103                 :             : 
     104         [ +  + ]:       25160 :         for (p = str; *p != '\0'; p++)
     105                 :             :         {
     106                 :             : 
     107                 :             :                 /* Only allow clean ASCII chars in the string */
     108   [ +  -  -  + ]:       24040 :                 if (*p < 32 || *p > 126)
     109                 :             :                 {
     110         [ #  # ]:           0 :                         Assert(i < (dstlen - 3));
     111                 :           0 :                         snprintf(&dst[i], dstlen - i, "\\x%02x", (unsigned char) *p);
     112                 :           0 :                         i += 4;
     113                 :           0 :                 }
     114                 :             :                 else
     115                 :             :                 {
     116         [ +  - ]:       24040 :                         Assert(i < dstlen);
     117                 :       24040 :                         dst[i] = *p;
     118                 :       24040 :                         i++;
     119                 :             :                 }
     120                 :       24040 :         }
     121                 :             : 
     122         [ +  - ]:        1120 :         Assert(i < dstlen);
     123                 :        1120 :         dst[i] = '\0';
     124                 :        1120 :         return dst;
     125                 :        1120 : }
     126                 :             : 
     127                 :             : 
     128                 :             : /*
     129                 :             :  * pg_is_ascii -- Check if string is made only of ASCII characters
     130                 :             :  */
     131                 :             : bool
     132                 :        7570 : pg_is_ascii(const char *str)
     133                 :             : {
     134         [ +  + ]:       21498 :         while (*str)
     135                 :             :         {
     136         [ -  + ]:       13928 :                 if (IS_HIGHBIT_SET(*str))
     137                 :           0 :                         return false;
     138                 :       13928 :                 str++;
     139                 :             :         }
     140                 :        7570 :         return true;
     141                 :        7570 : }
     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
     154                 :         594 : pg_strip_crlf(char *str)
     155                 :             : {
     156                 :         594 :         int                     len = strlen(str);
     157                 :             : 
     158   [ +  +  +  +  :        1782 :         while (len > 0 && (str[len - 1] == '\n' ||
                   +  + ]
     159                 :         576 :                                            str[len - 1] == '\r'))
     160                 :         594 :                 str[--len] = '\0';
     161                 :             : 
     162                 :        1188 :         return len;
     163                 :         594 : }
        

Generated by: LCOV version 2.3.2-1