ares_expand_string.c (3357B)
1 /* MIT License 2 * 3 * Copyright (c) 1998 Massachusetts Institute of Technology 4 * Copyright (c) The c-ares project and its contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * SPDX-License-Identifier: MIT 26 */ 27 28 #include "ares_private.h" 29 30 #ifdef HAVE_NETINET_IN_H 31 # include <netinet/in.h> 32 #endif 33 34 #include "ares_nameser.h" 35 36 /* Simply decodes a length-encoded character string. The first byte of the 37 * input is the length of the string to be returned and the bytes thereafter 38 * are the characters of the string. The returned result will be NULL 39 * terminated. 40 */ 41 ares_status_t ares_expand_string_ex(const unsigned char *encoded, 42 const unsigned char *abuf, size_t alen, 43 unsigned char **s, size_t *enclen) 44 { 45 ares_status_t status; 46 ares_buf_t *buf = NULL; 47 size_t start_len; 48 size_t len = 0; 49 50 if (encoded == NULL || abuf == NULL || alen == 0 || enclen == NULL) { 51 return ARES_EBADSTR; /* EFORMERR would be better */ 52 } 53 54 if (encoded < abuf || encoded >= abuf + alen) { 55 return ARES_EBADSTR; /* EFORMERR would be better */ 56 } 57 58 *enclen = 0; 59 60 /* NOTE: we allow 's' to be NULL to skip it */ 61 if (s) { 62 *s = NULL; 63 } 64 65 buf = ares_buf_create_const(abuf, alen); 66 67 if (buf == NULL) { 68 return ARES_ENOMEM; 69 } 70 71 status = ares_buf_set_position(buf, (size_t)(encoded - abuf)); 72 if (status != ARES_SUCCESS) { 73 goto done; 74 } 75 76 start_len = ares_buf_len(buf); 77 status = ares_buf_parse_dns_binstr(buf, ares_buf_len(buf), s, &len); 78 /* hrm, no way to pass back 'len' with the prototype */ 79 if (status != ARES_SUCCESS) { 80 goto done; 81 } 82 83 *enclen = start_len - ares_buf_len(buf); 84 85 done: 86 ares_buf_destroy(buf); 87 if (status == ARES_EBADNAME || status == ARES_EBADRESP) { 88 status = ARES_EBADSTR; 89 } 90 return status; 91 } 92 93 int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, 94 int alen, unsigned char **s, long *enclen) 95 { 96 ares_status_t status; 97 size_t temp_enclen = 0; 98 99 if (encoded == NULL || abuf == NULL || alen <= 0 || enclen == NULL) { 100 return ARES_EBADRESP; 101 } 102 103 status = ares_expand_string_ex(encoded, abuf, (size_t)alen, s, &temp_enclen); 104 105 *enclen = (long)temp_enclen; 106 return (int)status; 107 }