LCOV - code coverage report
Current view: top level - source3/lib - srprs.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 60 111 54.1 %
Date: 2021-09-23 10:06:22 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        6736 : bool srprs_skipws(const char** ptr) {
      34       14892 :         while (isspace(**ptr))
      35        1420 :                 ++(*ptr);
      36        6736 :         return true;
      37             : }
      38             : 
      39       11340 : bool srprs_char(const char** ptr, char c) {
      40       11340 :         if (**ptr == c) {
      41        6406 :                 ++(*ptr);
      42        6406 :                 return true;
      43             :         }
      44        4934 :         return false;
      45             : }
      46             : 
      47        8589 : bool srprs_str(const char** ptr, const char* str, ssize_t len)
      48             : {
      49             :         /* By definition *ptr must be null terminated. */
      50        8589 :         size_t ptr_len = strlen(*ptr);
      51             : 
      52        8589 :         if (len == -1)
      53        5910 :                 len = strlen(str);
      54             : 
      55             :         /* Don't memcmp read past end of buffer. */
      56        8589 :         if (len > ptr_len) {
      57         645 :                 return false;
      58             :         }
      59             : 
      60        7944 :         if (memcmp(*ptr, str, len) == 0) {
      61         394 :                 *ptr += len;
      62         394 :                 return true;
      63             :         }
      64        7550 :         return false;
      65             : }
      66             : 
      67        2691 : bool srprs_charset(const char** ptr, const char* set, cbuf* oss)
      68             : {
      69        2691 :         const char* p = strchr(set, **ptr);
      70        2691 :         if (p != NULL && *p != '\0') {
      71        1436 :                 cbuf_putc(oss, **ptr);
      72        1436 :                 ++(*ptr);
      73        1436 :                 return true;
      74             :         }
      75        1255 :         return false;
      76             : }
      77             : 
      78      112977 : bool srprs_charsetinv(const char** ptr, const char* set, cbuf* oss)
      79             : {
      80      112977 :         if ((**ptr != '\0') && (strchr(set, **ptr) == NULL)) {
      81      108288 :                 cbuf_putc(oss, **ptr);
      82      108288 :                 ++(*ptr);
      83      108288 :                 return true;
      84             :         }
      85        4689 :         return false;
      86             : }
      87             : 
      88             : 
      89             : 
      90        1944 : bool srprs_quoted_string(const char** ptr, cbuf* str, bool* cont)
      91             : {
      92        1944 :         const char* pos = *ptr;
      93        1944 :         const size_t spos = cbuf_getpos(str);
      94             : 
      95        1944 :         if (cont == NULL || *cont == false) {
      96        1944 :                 if (!srprs_char(&pos, '\"'))
      97           0 :                         goto fail;
      98             :         }
      99             : 
     100             :         while (true) {
     101        1976 :                 while (srprs_charsetinv(&pos, "\\\"", str))
     102             :                         ;
     103             : 
     104        1960 :                 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        1944 :                 case '\"':
     114        1944 :                         *ptr  = pos+1;
     115        1944 :                         if (cont != NULL) {
     116         972 :                                 *cont = false;
     117             :                         }
     118        1944 :                         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             :         int ret;
     141             :         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        2679 : bool srprs_nl(const char** ptr, cbuf* nl)
     164             : {
     165             :         static const char CRLF[] = "\r\n";
     166        2679 :         if (srprs_str(ptr, CRLF, sizeof(CRLF) - 1)) {
     167           4 :                 cbuf_puts(nl, CRLF, sizeof(CRLF) - 1);
     168           4 :                 return true;
     169             :         }
     170        2675 :         return srprs_charset(ptr, "\n\r", nl);
     171             : }
     172             : 
     173        4880 : bool srprs_eos(const char** ptr)
     174             : {
     175        4880 :         return (**ptr == '\0');
     176             : }
     177             : 
     178        2618 : bool srprs_eol(const char** ptr, cbuf* nl)
     179             : {
     180        2618 :         return  srprs_eos(ptr) || srprs_nl(ptr, nl);
     181             : }
     182             : 
     183        1493 : bool srprs_line(const char** ptr, cbuf* str)
     184             : {
     185        1493 :         while (srprs_charsetinv(ptr, "\n\r", str))
     186             :                 ;
     187        1493 :         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             :                                 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.13