LCOV - code coverage report
Current view: top level - ext/trunnel - trunnel.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 35 64 54.7 %
Date: 2021-11-24 03:28:48 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /* trunnel.c -- copied from Trunnel v1.5.3
       2             :  * https://gitweb.torproject.org/trunnel.git
       3             :  * You probably shouldn't edit this file.
       4             :  */
       5             : /* trunnel.c -- Helper functions to implement trunnel.
       6             :  *
       7             :  * Copyright 2014-2019, The Tor Project, Inc.
       8             :  * See license at the end of this file for copying information.
       9             :  *
      10             :  * See trunnel-impl.h for documentation of these functions.
      11             :  */
      12             : 
      13             : #include "trunnel-impl.h"
      14             : #include <stdlib.h>
      15             : #include <string.h>
      16             : 
      17             : #ifdef HAVE_SYS_PARAM_H
      18             : #include <sys/param.h>
      19             : #endif
      20             : 
      21             : #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
      22             :         __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
      23             : #  define IS_LITTLE_ENDIAN 1
      24             : #elif defined(BYTE_ORDER) && defined(ORDER_LITTLE_ENDIAN) &&     \
      25             :         BYTE_ORDER == __ORDER_LITTLE_ENDIAN
      26             : #  define IS_LITTLE_ENDIAN 1
      27             : #elif defined(_WIN32)
      28             : #  define IS_LITTLE_ENDIAN 1
      29             : #elif defined(__APPLE__)
      30             : #  include <libkern/OSByteOrder.h>
      31             : #  define BSWAP64(x) OSSwapLittleToHostInt64(x)
      32             : #elif defined(sun) || defined(__sun)
      33             : #  include <sys/byteorder.h>
      34             : #  ifndef _BIG_ENDIAN
      35             : #    define IS_LITTLE_ENDIAN
      36             : #  endif
      37             : #else
      38             : # if defined(__FreeBSD__) || defined(__NetBSD__) || defined(OpenBSD)
      39             : #  include <sys/endian.h>
      40             : # else
      41             : #  include <endian.h>
      42             : # endif
      43             : #  if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
      44             :         __BYTE_ORDER == __LITTLE_ENDIAN
      45             : #    define IS_LITTLE_ENDIAN
      46             : #  endif
      47             : #endif
      48             : 
      49             : #ifdef _WIN32
      50             : uint16_t
      51             : trunnel_htons(uint16_t s)
      52             : {
      53             :   return (s << 8) | (s >> 8);
      54             : }
      55             : uint16_t
      56             : trunnel_ntohs(uint16_t s)
      57             : {
      58             :   return (s << 8) | (s >> 8);
      59             : }
      60             : uint32_t
      61             : trunnel_htonl(uint32_t s)
      62             : {
      63             :   return (s << 24) |
      64             :          ((s << 8)&0xff0000) |
      65             :          ((s >> 8)&0xff00) |
      66             :          (s >> 24);
      67             : }
      68             : uint32_t
      69             : trunnel_ntohl(uint32_t s)
      70             : {
      71             :   return (s << 24) |
      72             :          ((s << 8)&0xff0000) |
      73             :          ((s >> 8)&0xff00) |
      74             :          (s >> 24);
      75             : }
      76             : #endif
      77             : 
      78             : uint64_t
      79          28 : trunnel_htonll(uint64_t a)
      80             : {
      81             : #ifdef IS_LITTLE_ENDIAN
      82          28 :   return trunnel_htonl((uint32_t)(a>>32))
      83          28 :     | (((uint64_t)trunnel_htonl((uint32_t)a))<<32);
      84             : #else
      85             :   return a;
      86             : #endif
      87             : }
      88             : 
      89             : uint64_t
      90          14 : trunnel_ntohll(uint64_t a)
      91             : {
      92          14 :   return trunnel_htonll(a);
      93             : }
      94             : 
      95             : #ifdef TRUNNEL_DEBUG_FAILING_ALLOC
      96             : /** Used for debugging and running tricky test cases: Makes the nth
      97             :  * memoryation allocation call from now fail.
      98             :  */
      99             : int trunnel_provoke_alloc_failure = 0;
     100             : #endif
     101             : 
     102             : void *
     103       30192 : trunnel_dynarray_expand(size_t *allocated_p, void *ptr,
     104             :                         size_t howmanymore, size_t eltsize)
     105             : {
     106       30192 :   size_t newsize = howmanymore + *allocated_p;
     107       30192 :   void *newarray = NULL;
     108       30192 :   if (newsize < 8)
     109             :     newsize = 8;
     110       30192 :   if (newsize < *allocated_p * 2)
     111             :     newsize = *allocated_p * 2;
     112       30192 :   if (newsize <= *allocated_p || newsize < howmanymore)
     113             :     return NULL;
     114       30192 :   newarray = trunnel_reallocarray(ptr, newsize, eltsize);
     115       30192 :   if (newarray == NULL)
     116             :     return NULL;
     117             : 
     118       30192 :   *allocated_p = newsize;
     119       30192 :   return newarray;
     120             : }
     121             : 
     122             : #ifndef trunnel_reallocarray
     123             : void *
     124             : trunnel_reallocarray(void *a, size_t x, size_t y)
     125             : {
     126             : #ifdef TRUNNEL_DEBUG_FAILING_ALLOC
     127             :    if (trunnel_provoke_alloc_failure) {
     128             :      if (--trunnel_provoke_alloc_failure == 0)
     129             :        return NULL;
     130             :    }
     131             : #endif
     132             :    if (x > SIZE_MAX / y)
     133             :      return NULL;
     134             :    return trunnel_realloc(a, x * y);
     135             : }
     136             : #endif
     137             : 
     138             : const char *
     139           0 : trunnel_string_getstr(trunnel_string_t *str)
     140             : {
     141           0 :   trunnel_assert(str->allocated_ >= str->n_);
     142           0 :   if (str->allocated_ == str->n_) {
     143           0 :     TRUNNEL_DYNARRAY_EXPAND(char, str, 1, {});
     144             :   }
     145           0 :   str->elts_[str->n_] = 0;
     146           0 :   return str->elts_;
     147           0 : trunnel_alloc_failed:
     148           0 :   return NULL;
     149             : }
     150             : 
     151             : int
     152         284 : trunnel_string_setstr0(trunnel_string_t *str, const char *val, size_t len,
     153             :                        uint8_t *errcode_ptr)
     154             : {
     155         284 :   if (len == SIZE_MAX)
     156           0 :     goto trunnel_alloc_failed;
     157         284 :   if (str->allocated_ <= len) {
     158         284 :     TRUNNEL_DYNARRAY_EXPAND(char, str, len + 1 - str->allocated_, {});
     159             :   }
     160         284 :   memcpy(str->elts_, val, len);
     161         284 :   str->n_ = len;
     162         284 :   str->elts_[len] = 0;
     163         284 :   return 0;
     164           0 : trunnel_alloc_failed:
     165           0 :   *errcode_ptr = 1;
     166           0 :   return -1;
     167             : }
     168             : 
     169             : int
     170           0 : trunnel_string_setlen(trunnel_string_t *str, size_t newlen,
     171             :                       uint8_t *errcode_ptr)
     172             : {
     173           0 :   if (newlen == SIZE_MAX)
     174           0 :     goto trunnel_alloc_failed;
     175           0 :   if (str->allocated_ < newlen + 1) {
     176           0 :     TRUNNEL_DYNARRAY_EXPAND(char, str, newlen + 1 - str->allocated_, {});
     177             :   }
     178           0 :   if (str->n_ < newlen) {
     179           0 :     memset(& (str->elts_[str->n_]), 0, (newlen - str->n_));
     180             :   }
     181           0 :   str->n_ = newlen;
     182           0 :   str->elts_[newlen] = 0;
     183           0 :   return 0;
     184             : 
     185           0 :  trunnel_alloc_failed:
     186           0 :   *errcode_ptr = 1;
     187           0 :   return -1;
     188             : }
     189             : 
     190             : void *
     191         530 : trunnel_dynarray_setlen(size_t *allocated_p, size_t *len_p,
     192             :                         void *ptr, size_t newlen,
     193             :                         size_t eltsize, trunnel_free_fn_t free_fn,
     194             :                         uint8_t *errcode_ptr)
     195             : {
     196         530 :   if (*allocated_p < newlen) {
     197         379 :     void *newptr = trunnel_dynarray_expand(allocated_p, ptr,
     198             :                                            newlen - *allocated_p, eltsize);
     199         379 :     if (newptr == NULL)
     200           0 :       goto trunnel_alloc_failed;
     201             :     ptr = newptr;
     202             :   }
     203         530 :   if (free_fn && *len_p > newlen) {
     204             :     size_t i;
     205             :     void **elts = (void **) ptr;
     206          10 :     for (i = newlen; i < *len_p; ++i) {
     207           5 :       free_fn(elts[i]);
     208           5 :       elts[i] = NULL;
     209             :     }
     210             :   }
     211         530 :   if (*len_p < newlen) {
     212         381 :     memset( ((char*)ptr) + (eltsize * *len_p), 0, (newlen - *len_p) * eltsize);
     213             :   }
     214         530 :   *len_p = newlen;
     215         530 :   return ptr;
     216           0 :  trunnel_alloc_failed:
     217           0 :   *errcode_ptr = 1;
     218           0 :   return NULL;
     219             : }
     220             : 
     221             : /*
     222             : Copyright 2014  The Tor Project, Inc.
     223             : 
     224             : Redistribution and use in source and binary forms, with or without
     225             : modification, are permitted provided that the following conditions are
     226             : met:
     227             : 
     228             :     * Redistributions of source code must retain the above copyright
     229             : notice, this list of conditions and the following disclaimer.
     230             : 
     231             :     * Redistributions in binary form must reproduce the above
     232             : copyright notice, this list of conditions and the following disclaimer
     233             : in the documentation and/or other materials provided with the
     234             : distribution.
     235             : 
     236             :     * Neither the names of the copyright owners nor the names of its
     237             : contributors may be used to endorse or promote products derived from
     238             : this software without specific prior written permission.
     239             : 
     240             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     241             : "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     242             : LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     243             : A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     244             : OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     245             : SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     246             : LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     247             : DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     248             : THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     249             : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     250             : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     251             : */

Generated by: LCOV version 1.14