Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/curl/lib/dotdot.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /*************************************************************************** | |
| 2 * _ _ ____ _ | |
| 3 * Project ___| | | | _ \| | | |
| 4 * / __| | | | |_) | | | |
| 5 * | (__| |_| | _ <| |___ | |
| 6 * \___|\___/|_| \_\_____| | |
| 7 * | |
| 8 * Copyright (C) 1998 - 2017, 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.haxx.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 ***************************************************************************/ | |
| 22 | |
| 23 #include "curl_setup.h" | |
| 24 | |
| 25 #include <curl/curl.h> | |
| 26 | |
| 27 #include "dotdot.h" | |
| 28 #include "curl_memory.h" | |
| 29 | |
| 30 /* The last #include file should be: */ | |
| 31 #include "memdebug.h" | |
| 32 | |
| 33 /* | |
| 34 * "Remove Dot Segments" | |
| 35 * https://tools.ietf.org/html/rfc3986#section-5.2.4 | |
| 36 */ | |
| 37 | |
| 38 /* | |
| 39 * Curl_dedotdotify() | |
| 40 * @unittest: 1395 | |
| 41 * | |
| 42 * This function gets a zero-terminated path with dot and dotdot sequences | |
| 43 * passed in and strips them off according to the rules in RFC 3986 section | |
| 44 * 5.2.4. | |
| 45 * | |
| 46 * The function handles a query part ('?' + stuff) appended but it expects | |
| 47 * that fragments ('#' + stuff) have already been cut off. | |
| 48 * | |
| 49 * RETURNS | |
| 50 * | |
| 51 * an allocated dedotdotified output string | |
| 52 */ | |
| 53 char *Curl_dedotdotify(const char *input) | |
| 54 { | |
| 55 size_t inlen = strlen(input); | |
| 56 char *clone; | |
| 57 size_t clen = inlen; /* the length of the cloned input */ | |
| 58 char *out = malloc(inlen + 1); | |
| 59 char *outptr; | |
| 60 char *orgclone; | |
| 61 char *queryp; | |
| 62 if(!out) | |
| 63 return NULL; /* out of memory */ | |
| 64 | |
| 65 *out = 0; /* zero terminates, for inputs like "./" */ | |
| 66 | |
| 67 /* get a cloned copy of the input */ | |
| 68 clone = strdup(input); | |
| 69 if(!clone) { | |
| 70 free(out); | |
| 71 return NULL; | |
| 72 } | |
| 73 orgclone = clone; | |
| 74 outptr = out; | |
| 75 | |
| 76 if(!*clone) { | |
| 77 /* zero length string, return that */ | |
| 78 free(out); | |
| 79 return clone; | |
| 80 } | |
| 81 | |
| 82 /* | |
| 83 * To handle query-parts properly, we must find it and remove it during the | |
| 84 * dotdot-operation and then append it again at the end to the output | |
| 85 * string. | |
| 86 */ | |
| 87 queryp = strchr(clone, '?'); | |
| 88 if(queryp) | |
| 89 *queryp = 0; | |
| 90 | |
| 91 do { | |
| 92 | |
| 93 /* A. If the input buffer begins with a prefix of "../" or "./", then | |
| 94 remove that prefix from the input buffer; otherwise, */ | |
| 95 | |
| 96 if(!strncmp("./", clone, 2)) { | |
| 97 clone += 2; | |
| 98 clen -= 2; | |
| 99 } | |
| 100 else if(!strncmp("../", clone, 3)) { | |
| 101 clone += 3; | |
| 102 clen -= 3; | |
| 103 } | |
| 104 | |
| 105 /* B. if the input buffer begins with a prefix of "/./" or "/.", where | |
| 106 "." is a complete path segment, then replace that prefix with "/" in | |
| 107 the input buffer; otherwise, */ | |
| 108 else if(!strncmp("/./", clone, 3)) { | |
| 109 clone += 2; | |
| 110 clen -= 2; | |
| 111 } | |
| 112 else if(!strcmp("/.", clone)) { | |
| 113 clone[1]='/'; | |
| 114 clone++; | |
| 115 clen -= 1; | |
| 116 } | |
| 117 | |
| 118 /* C. if the input buffer begins with a prefix of "/../" or "/..", where | |
| 119 ".." is a complete path segment, then replace that prefix with "/" in | |
| 120 the input buffer and remove the last segment and its preceding "/" (if | |
| 121 any) from the output buffer; otherwise, */ | |
| 122 | |
| 123 else if(!strncmp("/../", clone, 4)) { | |
| 124 clone += 3; | |
| 125 clen -= 3; | |
| 126 /* remove the last segment from the output buffer */ | |
| 127 while(outptr > out) { | |
| 128 outptr--; | |
| 129 if(*outptr == '/') | |
| 130 break; | |
| 131 } | |
| 132 *outptr = 0; /* zero-terminate where it stops */ | |
| 133 } | |
| 134 else if(!strcmp("/..", clone)) { | |
| 135 clone[2]='/'; | |
| 136 clone += 2; | |
| 137 clen -= 2; | |
| 138 /* remove the last segment from the output buffer */ | |
| 139 while(outptr > out) { | |
| 140 outptr--; | |
| 141 if(*outptr == '/') | |
| 142 break; | |
| 143 } | |
| 144 *outptr = 0; /* zero-terminate where it stops */ | |
| 145 } | |
| 146 | |
| 147 /* D. if the input buffer consists only of "." or "..", then remove | |
| 148 that from the input buffer; otherwise, */ | |
| 149 | |
| 150 else if(!strcmp(".", clone) || !strcmp("..", clone)) { | |
| 151 *clone = 0; | |
| 152 *out = 0; | |
| 153 } | |
| 154 | |
| 155 else { | |
| 156 /* E. move the first path segment in the input buffer to the end of | |
| 157 the output buffer, including the initial "/" character (if any) and | |
| 158 any subsequent characters up to, but not including, the next "/" | |
| 159 character or the end of the input buffer. */ | |
| 160 | |
| 161 do { | |
| 162 *outptr++ = *clone++; | |
| 163 clen--; | |
| 164 } while(*clone && (*clone != '/')); | |
| 165 *outptr = 0; | |
| 166 } | |
| 167 | |
| 168 } while(*clone); | |
| 169 | |
| 170 if(queryp) { | |
| 171 size_t qlen; | |
| 172 /* There was a query part, append that to the output. The 'clone' string | |
| 173 may now have been altered so we copy from the original input string | |
| 174 from the correct index. */ | |
| 175 size_t oindex = queryp - orgclone; | |
| 176 qlen = strlen(&input[oindex]); | |
| 177 memcpy(outptr, &input[oindex], qlen + 1); /* include the end zero byte */ | |
| 178 } | |
| 179 | |
| 180 free(orgclone); | |
| 181 return out; | |
| 182 } |
