xref: /curl/lib/strparse.c (revision d5c738c6)
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24 
25 #include "strparse.h"
26 
27 /* Get a word until the first DELIM or end of string. At least one byte long.
28    return non-zero on error */
Curl_str_until(char ** linep,struct Curl_str * out,const size_t max,char delim)29 int Curl_str_until(char **linep, struct Curl_str *out,
30                    const size_t max, char delim)
31 {
32   char *s = *linep;
33   size_t len = 0;
34   DEBUGASSERT(linep && *linep && out && max && delim);
35 
36   out->str = NULL;
37   out->len = 0;
38   while(*s && (*s != delim)) {
39     s++;
40     if(++len > max) {
41       return STRE_BIG;
42     }
43   }
44   if(!len)
45     return STRE_SHORT;
46   out->str = *linep;
47   out->len = len;
48   *linep = s; /* point to the first byte after the word */
49   return STRE_OK;
50 }
51 
52 /* Get a word until the first space or end of string. At least one byte long.
53    return non-zero on error */
Curl_str_word(char ** linep,struct Curl_str * out,const size_t max)54 int Curl_str_word(char **linep, struct Curl_str *out,
55                   const size_t max)
56 {
57   return Curl_str_until(linep, out, max, ' ');
58 }
59 
60 
61 /* Get a "quoted" word. No escaping possible.
62    return non-zero on error */
Curl_str_quotedword(char ** linep,struct Curl_str * out,const size_t max)63 int Curl_str_quotedword(char **linep, struct Curl_str *out,
64                         const size_t max)
65 {
66   char *s = *linep;
67   size_t len = 0;
68   DEBUGASSERT(linep && *linep && out && max);
69 
70   out->str = NULL;
71   out->len = 0;
72   if(*s != '\"')
73     return STRE_BEGQUOTE;
74   s++;
75   while(*s && (*s != '\"')) {
76     s++;
77     if(++len > max)
78       return STRE_BIG;
79   }
80   if(*s != '\"')
81     return STRE_ENDQUOTE;
82   out->str = (*linep) + 1;
83   out->len = len;
84   *linep = s + 1;
85   return STRE_OK;
86 }
87 
88 /* Advance over a single character.
89    return non-zero on error */
Curl_str_single(char ** linep,char byte)90 int Curl_str_single(char **linep, char byte)
91 {
92   DEBUGASSERT(linep && *linep);
93   if(**linep != byte)
94     return STRE_BYTE;
95   (*linep)++; /* move over it */
96   return STRE_OK;
97 }
98 
99 /* Advance over a single space.
100    return non-zero on error */
Curl_str_singlespace(char ** linep)101 int Curl_str_singlespace(char **linep)
102 {
103   return Curl_str_single(linep, ' ');
104 }
105 
106 /* Get an unsigned number. Leading zeroes are accepted.
107    return non-zero on error */
Curl_str_number(char ** linep,size_t * nump,size_t max)108 int Curl_str_number(char **linep, size_t *nump, size_t max)
109 {
110   size_t num = 0;
111   DEBUGASSERT(linep && *linep && nump);
112   *nump = 0;
113   while(ISDIGIT(**linep)) {
114     int n = **linep - '0';
115     if(num > ((SIZE_T_MAX - n) / 10))
116       return STRE_OVERFLOW;
117     num = num * 10 + n;
118     if(num > max)
119       return STRE_BIG; /** too big */
120     (*linep)++;
121   }
122   *nump = num;
123   return STRE_OK;
124 }
125 
126 /* CR or LF
127    return non-zero on error */
Curl_str_newline(char ** linep)128 int Curl_str_newline(char **linep)
129 {
130   DEBUGASSERT(linep && *linep);
131   if(ISNEWLINE(**linep)) {
132     (*linep)++;
133     return STRE_OK; /* yessir */
134   }
135   return STRE_NEWLINE;
136 }
137