LCOV - code coverage report
Current view: top level - source3/lib - srprs.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 60 115 52.2 %
Date: 2024-04-21 15:09:00 Functions: 10 12 83.3 %

          Line data    Source code
       1             : /*
       2             :  * Samba Unix/Linux SMB client library
       3             :  *
       4             :  * Copyright (C) Gregor Beck 2010
       5             :  *
       6             :  * This program is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * This program is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : /**
      21             :  * @file   srprs.c
      22             :  * @author Gregor Beck <gb@sernet.de>
      23             :  * @date   Aug 2010
      24             :  * @brief  A simple recursive parser.
      25             :  */
      26             : 
      27             : #include "replace.h"
      28             : #include "system/locale.h"
      29             : #include "srprs.h"
      30             : #include "cbuf.h"
      31             : #include <assert.h>
      32             : 
      33        7864 : bool srprs_skipws(const char** ptr) {
      34        9520 :         while (isspace(**ptr))
      35        1656 :                 ++(*ptr);
      36        7864 :         return true;
      37             : }
      38             : 
      39       12848 : bool srprs_char(const char** ptr, char c) {
      40       12848 :         if (**ptr == c) {
      41        7078 :                 ++(*ptr);
      42        7078 :                 return true;
      43             :         }
      44        5770 :         return false;
      45             : }
      46             : 
      47        9199 : bool srprs_str(const char** ptr, const char* str, ssize_t len)
      48             : {
      49             :         /* By definition *ptr must be null terminated. */
      50        9199 :         size_t ptr_len = strlen(*ptr);
      51             : 
      52        9199 :         if (len == -1)
      53        6074 :                 len = strlen(str);
      54             : 
      55             :         /* Don't memcmp read past end of buffer. */
      56        9199 :         if (len > ptr_len) {
      57         721 :                 return false;
      58             :         }
      59             : 
      60        8478 :         if (memcmp(*ptr, str, len) == 0) {
      61         394 :                 *ptr += len;
      62         394 :                 return true;
      63             :         }
      64        8084 :         return false;
      65             : }
      66             : 
      67        3137 : bool srprs_charset(const char** ptr, const char* set, cbuf* oss)
      68             : {
      69        3137 :         const char* p = strchr(set, **ptr);
      70        3137 :         if (p != NULL && *p != '\0') {
      71        1672 :                 cbuf_putc(oss, **ptr);
      72        1672 :                 ++(*ptr);
      73        1672 :                 return true;
      74             :         }
      75        1465 :         return false;
      76             : }
      77             : 
      78      131079 : bool srprs_charsetinv(const char** ptr, const char* set, cbuf* oss)
      79             : {
      80      131079 :         if ((**ptr != '\0') && (strchr(set, **ptr) == NULL)) {
      81      125600 :                 cbuf_putc(oss, **ptr);
      82      125600 :                 ++(*ptr);
      83      125600 :                 return true;
      84             :         }
      85        5479 :         return false;
      86             : }
      87             : 
      88             : 
      89             : 
      90        2272 : bool srprs_quoted_string(const char** ptr, cbuf* str, bool* cont)
      91             : {
      92        2272 :         const char* pos = *ptr;
      93        2272 :         const size_t spos = cbuf_getpos(str);
      94             : 
      95        2272 :         if (cont == NULL || *cont == false) {
      96        2272 :                 if (!srprs_char(&pos, '\"'))
      97           0 :                         goto fail;
      98             :         }
      99             : 
     100             :         while (true) {
     101       50917 :                 while (srprs_charsetinv(&pos, "\\\"", str))
     102             :                         ;
     103             : 
     104        2288 :                 switch (*pos) {
     105           0 :                 case '\0':
     106           0 :                         if (cont == NULL) {
     107           0 :                                 goto fail;
     108             :                         } else {
     109           0 :                                 *ptr = pos;
     110           0 :                                 *cont = true;
     111           0 :                                 return true;
     112             :                         }
     113        2272 :                 case '\"':
     114        2272 :                         *ptr  = pos+1;
     115        2272 :                         if (cont != NULL) {
     116        1136 :                                 *cont = false;
     117             :                         }
     118        2272 :                         return true;
     119             : 
     120          16 :                 case '\\':
     121          16 :                         pos++;
     122          16 :                         if (!srprs_charset(&pos, "\\\"", str))
     123           0 :                                 goto fail;
     124          16 :                         break;
     125             : 
     126           0 :                 default:
     127           0 :                         assert(false);
     128             :                 }
     129             :         }
     130             : 
     131           0 : fail:
     132           0 :         cbuf_setpos(str, spos);
     133           0 :         return false;
     134             : }
     135             : 
     136           0 : bool srprs_hex(const char** ptr, size_t len, unsigned* u)
     137             : {
     138           0 :         const char *str = *ptr;
     139           0 :         const char *pos = *ptr;
     140           0 :         int ret;
     141           0 :         size_t i;
     142           0 :         char buf[8+1] = {};
     143             : 
     144           0 :         assert((len >= 1) && (len <= 8));
     145             : 
     146           0 :         for (i=0; i<len; i++) {
     147           0 :                 if (!srprs_charset(&pos, "0123456789abcdefABCDEF", NULL)) {
     148           0 :                         break;
     149             :                 }
     150           0 :                 buf[i] = str[i];
     151             :         }
     152             : 
     153           0 :         ret = sscanf(buf, "%8x", u);
     154             : 
     155           0 :         if ( ret != 1 ) {
     156           0 :                 return false;
     157             :         }
     158             : 
     159           0 :         *ptr = pos;
     160           0 :         return true;
     161             : }
     162             : 
     163        3125 : bool srprs_nl(const char** ptr, cbuf* nl)
     164             : {
     165           0 :         static const char CRLF[] = "\r\n";
     166        3125 :         if (srprs_str(ptr, CRLF, sizeof(CRLF) - 1)) {
     167           4 :                 cbuf_puts(nl, CRLF, sizeof(CRLF) - 1);
     168           4 :                 return true;
     169             :         }
     170        3121 :         return srprs_charset(ptr, "\n\r", nl);
     171             : }
     172             : 
     173        5316 : bool srprs_eos(const char** ptr)
     174             : {
     175        5316 :         return (**ptr == '\0');
     176             : }
     177             : 
     178        3054 : bool srprs_eol(const char** ptr, cbuf* nl)
     179             : {
     180        3054 :         return  srprs_eos(ptr) || srprs_nl(ptr, nl);
     181             : }
     182             : 
     183        1739 : bool srprs_line(const char** ptr, cbuf* str)
     184             : {
     185       69340 :         while (srprs_charsetinv(ptr, "\n\r", str))
     186             :                 ;
     187        1739 :         return true;
     188             : }
     189             : 
     190           0 : bool srprs_quoted(const char** ptr, cbuf* str)
     191             : {
     192           0 :         const char* pos = *ptr;
     193           0 :         const size_t spos = cbuf_getpos(str);
     194             : 
     195           0 :         if (!srprs_char(&pos, '"')) {
     196           0 :                 goto fail;
     197             :         }
     198             : 
     199             :         while (true) {
     200           0 :                 while (srprs_charsetinv(&pos, "\\\"", str))
     201             :                         ;
     202             : 
     203           0 :                 switch (*pos) {
     204           0 :                 case '\0':
     205           0 :                         goto fail;
     206           0 :                 case '"':
     207           0 :                         *ptr  = pos+1;
     208           0 :                         return true;
     209             : 
     210           0 :                 case '\\':
     211           0 :                         pos++;
     212           0 :                         if (!srprs_charset(&pos, "\\\"", str)) {
     213           0 :                                 unsigned u;
     214           0 :                                 if (!srprs_hex(&pos, 2, &u)) {
     215           0 :                                         goto fail;
     216             :                                 }
     217           0 :                                 cbuf_putc(str, u);
     218             :                         }
     219           0 :                         break;
     220           0 :                 default:
     221           0 :                         assert(false);
     222             :                 }
     223             :         }
     224             : 
     225           0 : fail:
     226           0 :         cbuf_setpos(str, spos);
     227           0 :         return false;
     228             : }

Generated by: LCOV version 1.14