Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/curl/lib/base64.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 - 2019, 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 /* Base64 encoding/decoding */ | |
| 24 | |
| 25 #include "curl_setup.h" | |
| 26 | |
| 27 #if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \ | |
| 28 !defined(CURL_DISABLE_LDAP) || \ | |
| 29 !defined(CURL_DISABLE_DOH) || defined(USE_SSL) | |
| 30 | |
| 31 #include "urldata.h" /* for the Curl_easy definition */ | |
| 32 #include "warnless.h" | |
| 33 #include "curl_base64.h" | |
| 34 #include "non-ascii.h" | |
| 35 | |
| 36 /* The last 3 #include files should be in this order */ | |
| 37 #include "curl_printf.h" | |
| 38 #include "curl_memory.h" | |
| 39 #include "memdebug.h" | |
| 40 | |
| 41 /* ---- Base64 Encoding/Decoding Table --- */ | |
| 42 static const char base64[]= | |
| 43 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
| 44 | |
| 45 /* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648 | |
| 46 section 5 */ | |
| 47 static const char base64url[]= | |
| 48 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; | |
| 49 | |
| 50 static size_t decodeQuantum(unsigned char *dest, const char *src) | |
| 51 { | |
| 52 size_t padding = 0; | |
| 53 const char *s, *p; | |
| 54 unsigned long i, x = 0; | |
| 55 | |
| 56 for(i = 0, s = src; i < 4; i++, s++) { | |
| 57 if(*s == '=') { | |
| 58 x = (x << 6); | |
| 59 padding++; | |
| 60 } | |
| 61 else { | |
| 62 unsigned long v = 0; | |
| 63 p = base64; | |
| 64 | |
| 65 while(*p && (*p != *s)) { | |
| 66 v++; | |
| 67 p++; | |
| 68 } | |
| 69 | |
| 70 if(*p == *s) | |
| 71 x = (x << 6) + v; | |
| 72 else | |
| 73 return 0; | |
| 74 } | |
| 75 } | |
| 76 | |
| 77 if(padding < 1) | |
| 78 dest[2] = curlx_ultouc(x & 0xFFUL); | |
| 79 | |
| 80 x >>= 8; | |
| 81 if(padding < 2) | |
| 82 dest[1] = curlx_ultouc(x & 0xFFUL); | |
| 83 | |
| 84 x >>= 8; | |
| 85 dest[0] = curlx_ultouc(x & 0xFFUL); | |
| 86 | |
| 87 return 3 - padding; | |
| 88 } | |
| 89 | |
| 90 /* | |
| 91 * Curl_base64_decode() | |
| 92 * | |
| 93 * Given a base64 NUL-terminated string at src, decode it and return a | |
| 94 * pointer in *outptr to a newly allocated memory area holding decoded | |
| 95 * data. Size of decoded data is returned in variable pointed by outlen. | |
| 96 * | |
| 97 * Returns CURLE_OK on success, otherwise specific error code. Function | |
| 98 * output shall not be considered valid unless CURLE_OK is returned. | |
| 99 * | |
| 100 * When decoded data length is 0, returns NULL in *outptr. | |
| 101 * | |
| 102 * @unittest: 1302 | |
| 103 */ | |
| 104 CURLcode Curl_base64_decode(const char *src, | |
| 105 unsigned char **outptr, size_t *outlen) | |
| 106 { | |
| 107 size_t srclen = 0; | |
| 108 size_t length = 0; | |
| 109 size_t padding = 0; | |
| 110 size_t i; | |
| 111 size_t numQuantums; | |
| 112 size_t rawlen = 0; | |
| 113 unsigned char *pos; | |
| 114 unsigned char *newstr; | |
| 115 | |
| 116 *outptr = NULL; | |
| 117 *outlen = 0; | |
| 118 srclen = strlen(src); | |
| 119 | |
| 120 /* Check the length of the input string is valid */ | |
| 121 if(!srclen || srclen % 4) | |
| 122 return CURLE_BAD_CONTENT_ENCODING; | |
| 123 | |
| 124 /* Find the position of any = padding characters */ | |
| 125 while((src[length] != '=') && src[length]) | |
| 126 length++; | |
| 127 | |
| 128 /* A maximum of two = padding characters is allowed */ | |
| 129 if(src[length] == '=') { | |
| 130 padding++; | |
| 131 if(src[length + 1] == '=') | |
| 132 padding++; | |
| 133 } | |
| 134 | |
| 135 /* Check the = padding characters weren't part way through the input */ | |
| 136 if(length + padding != srclen) | |
| 137 return CURLE_BAD_CONTENT_ENCODING; | |
| 138 | |
| 139 /* Calculate the number of quantums */ | |
| 140 numQuantums = srclen / 4; | |
| 141 | |
| 142 /* Calculate the size of the decoded string */ | |
| 143 rawlen = (numQuantums * 3) - padding; | |
| 144 | |
| 145 /* Allocate our buffer including room for a zero terminator */ | |
| 146 newstr = malloc(rawlen + 1); | |
| 147 if(!newstr) | |
| 148 return CURLE_OUT_OF_MEMORY; | |
| 149 | |
| 150 pos = newstr; | |
| 151 | |
| 152 /* Decode the quantums */ | |
| 153 for(i = 0; i < numQuantums; i++) { | |
| 154 size_t result = decodeQuantum(pos, src); | |
| 155 if(!result) { | |
| 156 free(newstr); | |
| 157 | |
| 158 return CURLE_BAD_CONTENT_ENCODING; | |
| 159 } | |
| 160 | |
| 161 pos += result; | |
| 162 src += 4; | |
| 163 } | |
| 164 | |
| 165 /* Zero terminate */ | |
| 166 *pos = '\0'; | |
| 167 | |
| 168 /* Return the decoded data */ | |
| 169 *outptr = newstr; | |
| 170 *outlen = rawlen; | |
| 171 | |
| 172 return CURLE_OK; | |
| 173 } | |
| 174 | |
| 175 static CURLcode base64_encode(const char *table64, | |
| 176 struct Curl_easy *data, | |
| 177 const char *inputbuff, size_t insize, | |
| 178 char **outptr, size_t *outlen) | |
| 179 { | |
| 180 CURLcode result; | |
| 181 unsigned char ibuf[3]; | |
| 182 unsigned char obuf[4]; | |
| 183 int i; | |
| 184 int inputparts; | |
| 185 char *output; | |
| 186 char *base64data; | |
| 187 char *convbuf = NULL; | |
| 188 | |
| 189 const char *indata = inputbuff; | |
| 190 | |
| 191 *outptr = NULL; | |
| 192 *outlen = 0; | |
| 193 | |
| 194 if(!insize) | |
| 195 insize = strlen(indata); | |
| 196 | |
| 197 #if SIZEOF_SIZE_T == 4 | |
| 198 if(insize > UINT_MAX/4) | |
| 199 return CURLE_OUT_OF_MEMORY; | |
| 200 #endif | |
| 201 | |
| 202 base64data = output = malloc(insize * 4 / 3 + 4); | |
| 203 if(!output) | |
| 204 return CURLE_OUT_OF_MEMORY; | |
| 205 | |
| 206 /* | |
| 207 * The base64 data needs to be created using the network encoding | |
| 208 * not the host encoding. And we can't change the actual input | |
| 209 * so we copy it to a buffer, translate it, and use that instead. | |
| 210 */ | |
| 211 result = Curl_convert_clone(data, indata, insize, &convbuf); | |
| 212 if(result) { | |
| 213 free(output); | |
| 214 return result; | |
| 215 } | |
| 216 | |
| 217 if(convbuf) | |
| 218 indata = (char *)convbuf; | |
| 219 | |
| 220 while(insize > 0) { | |
| 221 for(i = inputparts = 0; i < 3; i++) { | |
| 222 if(insize > 0) { | |
| 223 inputparts++; | |
| 224 ibuf[i] = (unsigned char) *indata; | |
| 225 indata++; | |
| 226 insize--; | |
| 227 } | |
| 228 else | |
| 229 ibuf[i] = 0; | |
| 230 } | |
| 231 | |
| 232 obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2); | |
| 233 obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \ | |
| 234 ((ibuf[1] & 0xF0) >> 4)); | |
| 235 obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \ | |
| 236 ((ibuf[2] & 0xC0) >> 6)); | |
| 237 obuf[3] = (unsigned char) (ibuf[2] & 0x3F); | |
| 238 | |
| 239 switch(inputparts) { | |
| 240 case 1: /* only one byte read */ | |
| 241 msnprintf(output, 5, "%c%c==", | |
| 242 table64[obuf[0]], | |
| 243 table64[obuf[1]]); | |
| 244 break; | |
| 245 | |
| 246 case 2: /* two bytes read */ | |
| 247 msnprintf(output, 5, "%c%c%c=", | |
| 248 table64[obuf[0]], | |
| 249 table64[obuf[1]], | |
| 250 table64[obuf[2]]); | |
| 251 break; | |
| 252 | |
| 253 default: | |
| 254 msnprintf(output, 5, "%c%c%c%c", | |
| 255 table64[obuf[0]], | |
| 256 table64[obuf[1]], | |
| 257 table64[obuf[2]], | |
| 258 table64[obuf[3]]); | |
| 259 break; | |
| 260 } | |
| 261 output += 4; | |
| 262 } | |
| 263 | |
| 264 /* Zero terminate */ | |
| 265 *output = '\0'; | |
| 266 | |
| 267 /* Return the pointer to the new data (allocated memory) */ | |
| 268 *outptr = base64data; | |
| 269 | |
| 270 free(convbuf); | |
| 271 | |
| 272 /* Return the length of the new data */ | |
| 273 *outlen = strlen(base64data); | |
| 274 | |
| 275 return CURLE_OK; | |
| 276 } | |
| 277 | |
| 278 /* | |
| 279 * Curl_base64_encode() | |
| 280 * | |
| 281 * Given a pointer to an input buffer and an input size, encode it and | |
| 282 * return a pointer in *outptr to a newly allocated memory area holding | |
| 283 * encoded data. Size of encoded data is returned in variable pointed by | |
| 284 * outlen. | |
| 285 * | |
| 286 * Input length of 0 indicates input buffer holds a NUL-terminated string. | |
| 287 * | |
| 288 * Returns CURLE_OK on success, otherwise specific error code. Function | |
| 289 * output shall not be considered valid unless CURLE_OK is returned. | |
| 290 * | |
| 291 * When encoded data length is 0, returns NULL in *outptr. | |
| 292 * | |
| 293 * @unittest: 1302 | |
| 294 */ | |
| 295 CURLcode Curl_base64_encode(struct Curl_easy *data, | |
| 296 const char *inputbuff, size_t insize, | |
| 297 char **outptr, size_t *outlen) | |
| 298 { | |
| 299 return base64_encode(base64, data, inputbuff, insize, outptr, outlen); | |
| 300 } | |
| 301 | |
| 302 /* | |
| 303 * Curl_base64url_encode() | |
| 304 * | |
| 305 * Given a pointer to an input buffer and an input size, encode it and | |
| 306 * return a pointer in *outptr to a newly allocated memory area holding | |
| 307 * encoded data. Size of encoded data is returned in variable pointed by | |
| 308 * outlen. | |
| 309 * | |
| 310 * Input length of 0 indicates input buffer holds a NUL-terminated string. | |
| 311 * | |
| 312 * Returns CURLE_OK on success, otherwise specific error code. Function | |
| 313 * output shall not be considered valid unless CURLE_OK is returned. | |
| 314 * | |
| 315 * When encoded data length is 0, returns NULL in *outptr. | |
| 316 * | |
| 317 * @unittest: 1302 | |
| 318 */ | |
| 319 CURLcode Curl_base64url_encode(struct Curl_easy *data, | |
| 320 const char *inputbuff, size_t insize, | |
| 321 char **outptr, size_t *outlen) | |
| 322 { | |
| 323 return base64_encode(base64url, data, inputbuff, insize, outptr, outlen); | |
| 324 } | |
| 325 | |
| 326 #endif /* no users so disabled */ |
