/*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * SPDX-License-Identifier: curl * ***************************************************************************/ #include "strparse.h" /* Get a word until the first DELIM or end of string. At least one byte long. return non-zero on error */ int Curl_str_until(char **linep, struct Curl_str *out, const size_t max, char delim) { char *s = *linep; size_t len = 0; DEBUGASSERT(linep && *linep && out && max && delim); out->str = NULL; out->len = 0; while(*s && (*s != delim)) { s++; if(++len > max) { return STRE_BIG; } } if(!len) return STRE_SHORT; out->str = *linep; out->len = len; *linep = s; /* point to the first byte after the word */ return STRE_OK; } /* Get a word until the first space or end of string. At least one byte long. return non-zero on error */ int Curl_str_word(char **linep, struct Curl_str *out, const size_t max) { return Curl_str_until(linep, out, max, ' '); } /* Get a "quoted" word. No escaping possible. return non-zero on error */ int Curl_str_quotedword(char **linep, struct Curl_str *out, const size_t max) { char *s = *linep; size_t len = 0; DEBUGASSERT(linep && *linep && out && max); out->str = NULL; out->len = 0; if(*s != '\"') return STRE_BEGQUOTE; s++; while(*s && (*s != '\"')) { s++; if(++len > max) return STRE_BIG; } if(*s != '\"') return STRE_ENDQUOTE; out->str = (*linep) + 1; out->len = len; *linep = s + 1; return STRE_OK; } /* Advance over a single character. return non-zero on error */ int Curl_str_single(char **linep, char byte) { DEBUGASSERT(linep && *linep); if(**linep != byte) return STRE_BYTE; (*linep)++; /* move over it */ return STRE_OK; } /* Advance over a single space. return non-zero on error */ int Curl_str_singlespace(char **linep) { return Curl_str_single(linep, ' '); } /* Get an unsigned number. Leading zeroes are accepted. return non-zero on error */ int Curl_str_number(char **linep, size_t *nump, size_t max) { size_t num = 0; DEBUGASSERT(linep && *linep && nump); *nump = 0; while(ISDIGIT(**linep)) { int n = **linep - '0'; if(num > ((SIZE_T_MAX - n) / 10)) return STRE_OVERFLOW; num = num * 10 + n; if(num > max) return STRE_BIG; /** too big */ (*linep)++; } *nump = num; return STRE_OK; } /* CR or LF return non-zero on error */ int Curl_str_newline(char **linep) { DEBUGASSERT(linep && *linep); if(ISNEWLINE(**linep)) { (*linep)++; return STRE_OK; /* yessir */ } return STRE_NEWLINE; }