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