LCOV - differential code coverage report
Current view: top level - src/common - string.c (source / functions) Coverage Total Hit UNC GBC GIC GNC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 95.2 % 42 40 2 1 15 14 10 1 30
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 5 5 4 1 5
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * string.c
       4                 :  *      string handling helpers
       5                 :  *
       6                 :  *
       7                 :  * Portions Copyright (c) 1996-2023, 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                 : #include "lib/stringinfo.h"
      26                 : 
      27                 : 
      28                 : /*
      29                 :  * Returns whether the string `str' has the postfix `end'.
      30                 :  */
      31                 : bool
      32 GIC       14554 : pg_str_endswith(const char *str, const char *end)
      33 ECB             : {
      34 GIC       14554 :     size_t      slen = strlen(str);
      35 CBC       14554 :     size_t      elen = strlen(end);
      36 ECB             : 
      37                 :     /* can't be a postfix if longer */
      38 GIC       14554 :     if (elen > slen)
      39 CBC         143 :         return false;
      40 ECB             : 
      41                 :     /* compare the end of the strings */
      42 GIC       14411 :     str += slen - elen;
      43 CBC       14411 :     return strcmp(str, end) == 0;
      44 ECB             : }
      45                 : 
      46                 : 
      47                 : /*
      48                 :  * strtoint --- just like strtol, but returns int not long
      49                 :  */
      50                 : int
      51 GIC      183834 : strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
      52 ECB             : {
      53                 :     long        val;
      54                 : 
      55 GIC      183834 :     val = strtol(str, endptr, base);
      56 CBC      183834 :     if (val != (int) val)
      57               6 :         errno = ERANGE;
      58          183834 :     return (int) val;
      59 ECB             : }
      60                 : 
      61                 : 
      62                 : /*
      63                 :  * pg_clean_ascii -- Replace any non-ASCII chars with a "\xXX" string
      64                 :  *
      65                 :  * Makes a newly allocated copy of the string passed in, which must be
      66                 :  * '\0'-terminated. In the backend, additional alloc_flags may be provided and
      67                 :  * will be passed as-is to palloc_extended(); in the frontend, alloc_flags is
      68                 :  * ignored and the copy is malloc'd.
      69                 :  *
      70                 :  * This function exists specifically to deal with filtering out
      71                 :  * non-ASCII characters in a few places where the client can provide an almost
      72                 :  * arbitrary string (and it isn't checked to ensure it's a valid username or
      73                 :  * database name or similar) and we don't want to have control characters or other
      74                 :  * things ending up in the log file where server admins might end up with a
      75                 :  * messed up terminal when looking at them.
      76                 :  *
      77                 :  * In general, this function should NOT be used- instead, consider how to handle
      78                 :  * the string without needing to filter out the non-ASCII characters.
      79                 :  *
      80                 :  * Ultimately, we'd like to improve the situation to not require replacing all
      81                 :  * non-ASCII but perform more intelligent filtering which would allow UTF or
      82                 :  * similar, but it's unclear exactly what we should allow, so stick to ASCII only
      83                 :  * for now.
      84                 :  */
      85                 : char *
      86 GNC       23363 : pg_clean_ascii(const char *str, int alloc_flags)
      87                 : {
      88                 :     size_t      dstlen;
      89                 :     char       *dst;
      90                 :     const char *p;
      91           23363 :     size_t      i = 0;
      92                 : 
      93                 :     /* Worst case, each byte can become four bytes, plus a null terminator. */
      94           23363 :     dstlen = strlen(str) * 4 + 1;
      95                 : 
      96                 : #ifdef FRONTEND
      97 UNC           0 :     dst = malloc(dstlen);
      98                 : #else
      99 GNC       23363 :     dst = palloc_extended(dstlen, alloc_flags);
     100                 : #endif
     101                 : 
     102           23363 :     if (!dst)
     103 UNC           0 :         return NULL;
     104 ECB             : 
     105 GIC      404704 :     for (p = str; *p != '\0'; p++)
     106                 :     {
     107                 : 
     108                 :         /* Only allow clean ASCII chars in the string */
     109          381341 :         if (*p < 32 || *p > 126)
     110                 :         {
     111 GNC          16 :             Assert(i < (dstlen - 3));
     112              16 :             snprintf(&dst[i], dstlen - i, "\\x%02x", (unsigned char) *p);
     113              16 :             i += 4;
     114                 :         }
     115                 :         else
     116                 :         {
     117          381325 :             Assert(i < dstlen);
     118          381325 :             dst[i] = *p;
     119          381325 :             i++;
     120                 :         }
     121 ECB             :     }
     122                 : 
     123 GNC       23363 :     Assert(i < dstlen);
     124           23363 :     dst[i] = '\0';
     125           23363 :     return dst;
     126                 : }
     127                 : 
     128 ECB             : 
     129                 : /*
     130                 :  * pg_is_ascii -- Check if string is made only of ASCII characters
     131 EUB             :  */
     132                 : bool
     133 CBC      396435 : pg_is_ascii(const char *str)
     134                 : {
     135 GIC     2697969 :     while (*str)
     136 ECB             :     {
     137 GBC     2301542 :         if (IS_HIGHBIT_SET(*str))
     138 GIC           8 :             return false;
     139 CBC     2301534 :         str++;
     140                 :     }
     141 GIC      396427 :     return true;
     142                 : }
     143 ECB             : 
     144                 : 
     145                 : /*
     146                 :  * pg_strip_crlf -- Remove any trailing newline and carriage return
     147                 :  *
     148                 :  * Removes any trailing newline and carriage return characters (\r on
     149                 :  * Windows) in the input string, zero-terminating it.
     150                 :  *
     151                 :  * The passed in string must be zero-terminated.  This function returns
     152                 :  * the new length of the string.
     153                 :  */
     154                 : int
     155 GIC      126475 : pg_strip_crlf(char *str)
     156                 : {
     157 CBC      126475 :     int         len = strlen(str);
     158 ECB             : 
     159 CBC      252950 :     while (len > 0 && (str[len - 1] == '\n' ||
     160 GIC      122282 :                        str[len - 1] == '\r'))
     161          126475 :         str[--len] = '\0';
     162                 : 
     163          126475 :     return len;
     164                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a