LCOV - code coverage report
Current view: top level - fuzz - miscutil.c (source / functions) Hit Total Coverage
Test: trace.lcov_info_final Lines: 131 165 79.4 %
Date: 2021-02-22 04:51:02 Functions: 19 21 90.5 %

          Line data    Source code
       1             : /*********************************************************************
       2             :  *
       3             :  * File        :  $Source: /cvsroot/ijbswa/current/miscutil.c,v $
       4             :  *
       5             :  * Purpose     :  zalloc, hash_string, strcmpic, strncmpic, and
       6             :  *                MinGW32 strdup functions.  These are each too small
       7             :  *                to deserve their own file but don't really fit in
       8             :  *                any other file.
       9             :  *
      10             :  * Copyright   :  Written by and Copyright (C) 2001-2020 the
      11             :  *                Privoxy team. https://www.privoxy.org/
      12             :  *
      13             :  *                Based on the Internet Junkbuster originally written
      14             :  *                by and Copyright (C) 1997 Anonymous Coders and
      15             :  *                Junkbusters Corporation.  http://www.junkbusters.com
      16             :  *
      17             :  *                The timegm replacement function was taken from GnuPG,
      18             :  *                Copyright (C) 2004 Free Software Foundation, Inc.
      19             :  *
      20             :  *                This program is free software; you can redistribute it
      21             :  *                and/or modify it under the terms of the GNU General
      22             :  *                Public License as published by the Free Software
      23             :  *                Foundation; either version 2 of the License, or (at
      24             :  *                your option) any later version.
      25             :  *
      26             :  *                This program is distributed in the hope that it will
      27             :  *                be useful, but WITHOUT ANY WARRANTY; without even the
      28             :  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
      29             :  *                PARTICULAR PURPOSE.  See the GNU General Public
      30             :  *                License for more details.
      31             :  *
      32             :  *                The GNU General Public License should be included with
      33             :  *                this file.  If not, you can view it at
      34             :  *                http://www.gnu.org/copyleft/gpl.html
      35             :  *                or write to the Free Software Foundation, Inc., 59
      36             :  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
      37             :  *
      38             :  *********************************************************************/
      39             : 
      40             : 
      41             : #include "config.h"
      42             : 
      43             : #include <stdio.h>
      44             : #include <sys/types.h>
      45             : #include <stdlib.h>
      46             : #if !defined(_WIN32)
      47             : #include <unistd.h>
      48             : #endif /* #if !defined(_WIN32) */
      49             : #include <string.h>
      50             : #include <ctype.h>
      51             : #include <assert.h>
      52             : 
      53             : #if !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV)
      54             : #include <time.h>
      55             : #endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
      56             : 
      57             : #include "project.h"
      58             : #include "miscutil.h"
      59             : #include "jcc.h"
      60             : #include "errlog.h"
      61             : 
      62             : /*********************************************************************
      63             :  *
      64             :  * Function    :  zalloc
      65             :  *
      66             :  * Description :  Returns allocated memory that is initialized
      67             :  *                with zeros.
      68             :  *
      69             :  * Parameters  :
      70             :  *          1  :  size = Size of memory chunk to return.
      71             :  *
      72             :  * Returns     :  Pointer to newly alloc'd memory chunk.
      73             :  *
      74             :  *********************************************************************/
      75     3903662 : void *zalloc(size_t size)
      76             : {
      77             :    void * ret;
      78             : 
      79             : #ifdef HAVE_CALLOC
      80     3903662 :    ret = calloc(1, size);
      81             : #else
      82             : #warning calloc appears to be unavailable. Your platform will become unsupported in the future
      83             :    if ((ret = (void *)malloc(size)) != NULL)
      84             :    {
      85             :       memset(ret, 0, size);
      86             :    }
      87             : #endif
      88             : 
      89     3903662 :    return(ret);
      90             : 
      91             : }
      92             : 
      93             : 
      94             : /*********************************************************************
      95             :  *
      96             :  * Function    :  zalloc_or_die
      97             :  *
      98             :  * Description :  zalloc wrapper that either succeeds or causes
      99             :  *                program termination.
     100             :  *
     101             :  *                Useful in situations were the string length is
     102             :  *                "small" and zalloc() failures couldn't be handled
     103             :  *                better anyway. In case of debug builds, failures
     104             :  *                trigger an assert().
     105             :  *
     106             :  * Parameters  :
     107             :  *          1  :  size = Size of memory chunk to return.
     108             :  *
     109             :  * Returns     :  Pointer to newly malloc'd memory chunk.
     110             :  *
     111             :  *********************************************************************/
     112      420465 : void *zalloc_or_die(size_t size)
     113             : {
     114             :    void *buffer;
     115             : 
     116      420465 :    buffer = zalloc(size);
     117      420465 :    if (buffer == NULL)
     118             :    {
     119           0 :       assert(buffer != NULL);
     120           0 :       log_error(LOG_LEVEL_FATAL, "Out of memory in zalloc_or_die().");
     121           0 :       exit(1);
     122             :    }
     123             : 
     124      420465 :    return(buffer);
     125             : 
     126             : }
     127             : 
     128             : /*********************************************************************
     129             :  *
     130             :  * Function    :  strdup_or_die
     131             :  *
     132             :  * Description :  strdup wrapper that either succeeds or causes
     133             :  *                program termination.
     134             :  *
     135             :  *                Useful in situations were the string length is
     136             :  *                "small" and strdup() failures couldn't be handled
     137             :  *                better anyway. In case of debug builds, failures
     138             :  *                trigger an assert().
     139             :  *
     140             :  * Parameters  :
     141             :  *          1  :  str = String to duplicate
     142             :  *
     143             :  * Returns     :  Pointer to newly strdup'd copy of the string.
     144             :  *
     145             :  *********************************************************************/
     146     2290074 : char *strdup_or_die(const char *str)
     147             : {
     148             :    char *new_str;
     149             : 
     150     2290074 :    new_str = strdup(str);
     151             : 
     152     2290074 :    if (new_str == NULL)
     153             :    {
     154           0 :       assert(new_str != NULL);
     155           0 :       log_error(LOG_LEVEL_FATAL, "Out of memory in strdup_or_die().");
     156           0 :       exit(1);
     157             :    }
     158             : 
     159     2290074 :    return(new_str);
     160             : 
     161             : }
     162             : 
     163             : 
     164             : /*********************************************************************
     165             :  *
     166             :  * Function    :  malloc_or_die
     167             :  *
     168             :  * Description :  malloc wrapper that either succeeds or causes
     169             :  *                program termination.
     170             :  *
     171             :  *                Useful in situations were the buffer size is "small"
     172             :  *                and malloc() failures couldn't be handled better
     173             :  *                anyway. In case of debug builds, failures trigger
     174             :  *                an assert().
     175             :  *
     176             :  * Parameters  :
     177             :  *          1  :  buffer_size = Size of the space to allocate
     178             :  *
     179             :  * Returns     :  Pointer to newly malloc'd memory
     180             :  *
     181             :  *********************************************************************/
     182      193395 : void *malloc_or_die(size_t buffer_size)
     183             : {
     184             :    char *new_buf;
     185             : 
     186      193395 :    if (buffer_size == 0)
     187             :    {
     188           0 :       log_error(LOG_LEVEL_ERROR,
     189             :          "malloc_or_die() called with buffer size 0");
     190           0 :       assert(buffer_size != 0);
     191           0 :       buffer_size = 4096;
     192             :    }
     193             : 
     194      193395 :    new_buf = malloc(buffer_size);
     195             : 
     196      193395 :    if (new_buf == NULL)
     197             :    {
     198           0 :       assert(new_buf != NULL);
     199           0 :       log_error(LOG_LEVEL_FATAL, "Out of memory in malloc_or_die().");
     200           0 :       exit(1);
     201             :    }
     202             : 
     203      193395 :    return(new_buf);
     204             : 
     205             : }
     206             : 
     207             : 
     208             : #if defined(unix)
     209             : /*********************************************************************
     210             :  *
     211             :  * Function    :  write_pid_file
     212             :  *
     213             :  * Description :  Writes a pid file with the pid of the main process.
     214             :  *                Exits if the file can't be opened
     215             :  *
     216             :  * Parameters  :
     217             :  *          1  :  pid_file = Path of the pid file that gets created.
     218             :  *
     219             :  * Returns     :  N/A
     220             :  *
     221             :  *********************************************************************/
     222           0 : void write_pid_file(const char *pid_file)
     223             : {
     224             :    FILE   *fp;
     225             : 
     226           0 :    if ((fp = fopen(pid_file, "w")) == NULL)
     227             :    {
     228           0 :       log_error(LOG_LEVEL_FATAL, "can't open pid file '%s': %E", pid_file);
     229             :    }
     230             :    else
     231             :    {
     232           0 :       fprintf(fp, "%u\n", (unsigned int) getpid());
     233           0 :       fclose (fp);
     234             :    }
     235           0 :    return;
     236             : 
     237             : }
     238             : #endif /* def unix */
     239             : 
     240             : 
     241             : /*********************************************************************
     242             :  *
     243             :  * Function    :  hash_string
     244             :  *
     245             :  * Description :  Take a string and compute a (hopefully) unique numeric
     246             :  *                integer value. This is useful to "switch" a string.
     247             :  *
     248             :  * Parameters  :
     249             :  *          1  :  s : string to be hashed.
     250             :  *
     251             :  * Returns     :  The string's hash
     252             :  *
     253             :  *********************************************************************/
     254      173488 : unsigned int hash_string(const char* s)
     255             : {
     256      173488 :    unsigned int h = 0;
     257             : 
     258     2518674 :    for (; *s; ++s)
     259             :    {
     260     2345186 :       h = 5 * h + (unsigned int)*s;
     261             :    }
     262             : 
     263      173488 :    return (h);
     264             : 
     265             : }
     266             : 
     267             : 
     268             : /*********************************************************************
     269             :  *
     270             :  * Function    :  strcmpic
     271             :  *
     272             :  * Description :  Case insensitive string comparison
     273             :  *
     274             :  * Parameters  :
     275             :  *          1  :  s1 = string 1 to compare
     276             :  *          2  :  s2 = string 2 to compare
     277             :  *
     278             :  * Returns     :  0 if s1==s2, Negative if s1<s2, Positive if s1>s2
     279             :  *
     280             :  *********************************************************************/
     281    13399934 : int strcmpic(const char *s1, const char *s2)
     282             : {
     283    13399934 :    if (!s1) s1 = "";
     284    13399934 :    if (!s2) s2 = "";
     285             : 
     286    29717741 :    while (*s1 && *s2)
     287             :    {
     288    29145733 :       if ((*s1 != *s2) && (privoxy_tolower(*s1) != privoxy_tolower(*s2)))
     289             :       {
     290    12827926 :          break;
     291             :       }
     292    16317807 :       s1++, s2++;
     293             :    }
     294    13399934 :    return(privoxy_tolower(*s1) - privoxy_tolower(*s2));
     295             : 
     296             : }
     297             : 
     298             : 
     299             : /*********************************************************************
     300             :  *
     301             :  * Function    :  strncmpic
     302             :  *
     303             :  * Description :  Case insensitive string comparison (up to n characters)
     304             :  *
     305             :  * Parameters  :
     306             :  *          1  :  s1 = string 1 to compare
     307             :  *          2  :  s2 = string 2 to compare
     308             :  *          3  :  n = maximum characters to compare
     309             :  *
     310             :  * Returns     :  0 if s1==s2, Negative if s1<s2, Positive if s1>s2
     311             :  *
     312             :  *********************************************************************/
     313    13932347 : int strncmpic(const char *s1, const char *s2, size_t n)
     314             : {
     315    13932347 :    if (n <= (size_t)0) return(0);
     316    13122572 :    if (!s1) s1 = "";
     317    13122572 :    if (!s2) s2 = "";
     318             : 
     319    19054418 :    while (*s1 && *s2)
     320             :    {
     321    18943736 :       if ((*s1 != *s2) && (privoxy_tolower(*s1) != privoxy_tolower(*s2)))
     322             :       {
     323    12240437 :          break;
     324             :       }
     325             : 
     326     6703299 :       if (--n <= (size_t)0) break;
     327             : 
     328     5931846 :       s1++, s2++;
     329             :    }
     330    13122572 :    return(privoxy_tolower(*s1) - privoxy_tolower(*s2));
     331             : 
     332             : }
     333             : 
     334             : 
     335             : /*********************************************************************
     336             :  *
     337             :  * Function    :  chomp
     338             :  *
     339             :  * Description :  In-situ-eliminate all leading and trailing whitespace
     340             :  *                from a string.
     341             :  *
     342             :  * Parameters  :
     343             :  *          1  :  s : string to be chomped.
     344             :  *
     345             :  * Returns     :  chomped string
     346             :  *
     347             :  *********************************************************************/
     348     1055466 : char *chomp(char *string)
     349             : {
     350             :    char *p, *q, *r;
     351             : 
     352             :    /*
     353             :     * strip trailing whitespace
     354             :     */
     355     1055466 :    p = string + strlen(string);
     356     1226774 :    while (p > string && privoxy_isspace(*(p-1)))
     357             :    {
     358      171308 :       p--;
     359             :    }
     360     1055466 :    *p = '\0';
     361             : 
     362             :    /*
     363             :     * find end of leading whitespace
     364             :     */
     365     1055466 :    q = r = string;
     366     1113088 :    while (*q && privoxy_isspace(*q))
     367             :    {
     368       57622 :       q++;
     369             :    }
     370             : 
     371             :    /*
     372             :     * if there was any, move the rest forwards
     373             :     */
     374     1055466 :    if (q != string)
     375             :    {
     376     4768865 :       while (q <= p)
     377             :       {
     378     4727913 :          *r++ = *q++;
     379             :       }
     380             :    }
     381             : 
     382     1055466 :    return(string);
     383             : 
     384             : }
     385             : 
     386             : 
     387             : /*********************************************************************
     388             :  *
     389             :  * Function    :  string_append
     390             :  *
     391             :  * Description :  Reallocate target_string and append text to it.
     392             :  *                This makes it easier to append to malloc'd strings.
     393             :  *                This is similar to the (removed) strsav(), but
     394             :  *                running out of memory isn't catastrophic.
     395             :  *
     396             :  *                Programming style:
     397             :  *
     398             :  *                The following style provides sufficient error
     399             :  *                checking for this routine, with minimal clutter
     400             :  *                in the source code.  It is recommended if you
     401             :  *                have many calls to this function:
     402             :  *
     403             :  *                char * s = strdup(...); // don't check for error
     404             :  *                string_append(&s, ...);  // don't check for error
     405             :  *                string_append(&s, ...);  // don't check for error
     406             :  *                string_append(&s, ...);  // don't check for error
     407             :  *                if (NULL == s) { ... handle error ... }
     408             :  *
     409             :  *                OR, equivalently:
     410             :  *
     411             :  *                char * s = strdup(...); // don't check for error
     412             :  *                string_append(&s, ...);  // don't check for error
     413             :  *                string_append(&s, ...);  // don't check for error
     414             :  *                if (string_append(&s, ...)) {... handle error ...}
     415             :  *
     416             :  * Parameters  :
     417             :  *          1  :  target_string = Pointer to old text that is to be
     418             :  *                extended.  *target_string will be free()d by this
     419             :  *                routine.  target_string must be non-NULL.
     420             :  *                If *target_string is NULL, this routine will
     421             :  *                do nothing and return with an error - this allows
     422             :  *                you to make many calls to this routine and only
     423             :  *                check for errors after the last one.
     424             :  *          2  :  text_to_append = Text to be appended to old.
     425             :  *                Must not be NULL.
     426             :  *
     427             :  * Returns     :  JB_ERR_OK on success, and sets *target_string
     428             :  *                   to newly malloc'ed appended string.  Caller
     429             :  *                   must free(*target_string).
     430             :  *                JB_ERR_MEMORY on out-of-memory.  (And free()s
     431             :  *                   *target_string and sets it to NULL).
     432             :  *                JB_ERR_MEMORY if *target_string is NULL.
     433             :  *
     434             :  *********************************************************************/
     435    12315316 : jb_err string_append(char **target_string, const char *text_to_append)
     436             : {
     437             :    size_t old_len;
     438             :    char *new_string;
     439             :    size_t new_size;
     440             : 
     441    12315316 :    assert(target_string);
     442    12315316 :    assert(text_to_append);
     443             : 
     444    12315316 :    if (*target_string == NULL)
     445             :    {
     446           0 :       return JB_ERR_MEMORY;
     447             :    }
     448             : 
     449    12315316 :    if (*text_to_append == '\0')
     450             :    {
     451       62753 :       return JB_ERR_OK;
     452             :    }
     453             : 
     454    12252563 :    old_len = strlen(*target_string);
     455             : 
     456    12252563 :    new_size = strlen(text_to_append) + old_len + 1;
     457             : 
     458    12252563 :    if (NULL == (new_string = realloc(*target_string, new_size)))
     459             :    {
     460           0 :       free(*target_string);
     461             : 
     462           0 :       *target_string = NULL;
     463           0 :       return JB_ERR_MEMORY;
     464             :    }
     465             : 
     466    12252563 :    strlcpy(new_string + old_len, text_to_append, new_size - old_len);
     467             : 
     468    12252563 :    *target_string = new_string;
     469    12252563 :    return JB_ERR_OK;
     470             : }
     471             : 
     472             : 
     473             : /*********************************************************************
     474             :  *
     475             :  * Function    :  string_join
     476             :  *
     477             :  * Description :  Join two strings together.  Frees BOTH the original
     478             :  *                strings.  If either or both input strings are NULL,
     479             :  *                fails as if it had run out of memory.
     480             :  *
     481             :  *                For comparison, string_append requires that the
     482             :  *                second string is non-NULL, and doesn't free it.
     483             :  *
     484             :  *                Rationale: Too often, we want to do
     485             :  *                string_append(s, html_encode(s2)).  That assert()s
     486             :  *                if s2 is NULL or if html_encode() runs out of memory.
     487             :  *                It also leaks memory.  Proper checking is cumbersome.
     488             :  *                The solution: string_join(s, html_encode(s2)) is safe,
     489             :  *                and will free the memory allocated by html_encode().
     490             :  *
     491             :  * Parameters  :
     492             :  *          1  :  target_string = Pointer to old text that is to be
     493             :  *                extended.  *target_string will be free()d by this
     494             :  *                routine.  target_string must be non-NULL.
     495             :  *          2  :  text_to_append = Text to be appended to old.
     496             :  *
     497             :  * Returns     :  JB_ERR_OK on success, and sets *target_string
     498             :  *                   to newly malloc'ed appended string.  Caller
     499             :  *                   must free(*target_string).
     500             :  *                JB_ERR_MEMORY on out-of-memory, or if
     501             :  *                   *target_string or text_to_append is NULL.  (In
     502             :  *                   this case, frees *target_string and text_to_append,
     503             :  *                   sets *target_string to NULL).
     504             :  *
     505             :  *********************************************************************/
     506     1126725 : jb_err string_join(char **target_string, char *text_to_append)
     507             : {
     508             :    jb_err err;
     509             : 
     510     1126725 :    assert(target_string);
     511             : 
     512     1126725 :    if (text_to_append == NULL)
     513             :    {
     514           0 :       freez(*target_string);
     515           0 :       return JB_ERR_MEMORY;
     516             :    }
     517             : 
     518     1126725 :    err = string_append(target_string, text_to_append);
     519             : 
     520     1126725 :    freez(text_to_append);
     521             : 
     522     1126725 :    return err;
     523             : }
     524             : 
     525             : 
     526             : /*********************************************************************
     527             :  *
     528             :  * Function    :  string_toupper
     529             :  *
     530             :  * Description :  Produce a copy of string with all convertible
     531             :  *                characters converted to uppercase.
     532             :  *
     533             :  * Parameters  :
     534             :  *          1  :  string = string to convert
     535             :  *
     536             :  * Returns     :  Uppercase copy of string if possible,
     537             :  *                NULL on out-of-memory or if string was NULL.
     538             :  *
     539             :  *********************************************************************/
     540      388760 : char *string_toupper(const char *string)
     541             : {
     542             :    char *result, *p;
     543             :    const char *q;
     544             : 
     545      388760 :    if (!string || ((result = (char *) zalloc(strlen(string) + 1)) == NULL))
     546             :    {
     547           0 :       return NULL;
     548             :    }
     549             : 
     550      388760 :    q = string;
     551      388760 :    p = result;
     552             : 
     553     6259220 :    while (*q != '\0')
     554             :    {
     555     5870460 :       *p++ = (char)toupper((int) *q++);
     556             :    }
     557             : 
     558      388760 :    return result;
     559             : 
     560             : }
     561             : 
     562             : 
     563             : /*********************************************************************
     564             :  *
     565             :  * Function    :  string_tolower
     566             :  *
     567             :  * Description :  Produce a copy of string with all convertible
     568             :  *                characters converted to lowercase.
     569             :  *
     570             :  * Parameters  :
     571             :  *          1  :  string = string to convert
     572             :  *
     573             :  * Returns     :  Lowercase copy of string if possible,
     574             :  *                NULL on out-of-memory or if string was NULL.
     575             :  *
     576             :  *********************************************************************/
     577       52471 : char *string_tolower(const char *string)
     578             : {
     579             :    char *result, *p;
     580             :    const char *q;
     581             : 
     582       52471 :    if (!string || ((result = (char *)zalloc(strlen(string) + 1)) == NULL))
     583             :    {
     584           0 :       return NULL;
     585             :    }
     586             : 
     587       52471 :    q = string;
     588       52471 :    p = result;
     589             : 
     590      636727 :    while (*q != '\0')
     591             :    {
     592      584256 :       *p++ = (char)privoxy_tolower(*q++);
     593             :    }
     594             : 
     595       52471 :    return result;
     596             : 
     597             : }
     598             : 
     599             : 
     600             : /*********************************************************************
     601             :  *
     602             :  * Function    :  string_move
     603             :  *
     604             :  * Description :  memmove wrapper to move the last part of a string
     605             :  *                towards the beginning, overwriting the part in
     606             :  *                the middle. strlcpy() can't be used here as the
     607             :  *                strings overlap.
     608             :  *
     609             :  * Parameters  :
     610             :  *          1  :  dst = Destination to overwrite
     611             :  *          2  :  src = Source to move.
     612             :  *
     613             :  * Returns     :  N/A
     614             :  *
     615             :  *********************************************************************/
     616        5766 : void string_move(char *dst, char *src)
     617             : {
     618        5766 :    assert(dst < src);
     619             : 
     620             :    /* +1 to copy the terminating nul as well. */
     621        5766 :    memmove(dst, src, strlen(src)+1);
     622        5766 : }
     623             : 
     624             : 
     625             : /*********************************************************************
     626             :  *
     627             :  * Function    :  bindup
     628             :  *
     629             :  * Description :  Duplicate the first n characters of a string that may
     630             :  *                contain '\0' characters.
     631             :  *
     632             :  * Parameters  :
     633             :  *          1  :  string = string to be duplicated
     634             :  *          2  :  len = number of bytes to duplicate
     635             :  *
     636             :  * Returns     :  pointer to copy, or NULL if failure
     637             :  *
     638             :  *********************************************************************/
     639        1426 : char *bindup(const char *string, size_t len)
     640             : {
     641             :    char *duplicate;
     642             : 
     643        1426 :    duplicate = (char *)malloc(len);
     644        1426 :    if (NULL != duplicate)
     645             :    {
     646        1426 :       memcpy(duplicate, string, len);
     647             :    }
     648             : 
     649        1426 :    return duplicate;
     650             : 
     651             : }
     652             : 
     653             : 
     654             : /*********************************************************************
     655             :  *
     656             :  * Function    :  make_path
     657             :  *
     658             :  * Description :  Takes a directory name and a file name, returns
     659             :  *                the complete path.  Handles windows/unix differences.
     660             :  *                If the file name is already an absolute path, or if
     661             :  *                the directory name is NULL or empty, it returns
     662             :  *                the filename.
     663             :  *
     664             :  * Parameters  :
     665             :  *          1  :  dir: Name of directory or NULL for none.
     666             :  *          2  :  file: Name of file.  Should not be NULL or empty.
     667             :  *
     668             :  * Returns     :  "dir/file" (Or on windows, "dir\file").
     669             :  *                It allocates the string on the heap.  Caller frees.
     670             :  *                Returns NULL in error (i.e. NULL file or out of
     671             :  *                memory)
     672             :  *
     673             :  *********************************************************************/
     674      242349 : char * make_path(const char * dir, const char * file)
     675             : {
     676      242349 :    if ((file == NULL) || (*file == '\0'))
     677             :    {
     678           0 :       return NULL; /* Error */
     679             :    }
     680             : 
     681      242349 :    if ((dir == NULL) || (*dir == '\0') /* No directory specified */
     682             : #if defined(_WIN32)
     683             :       || (*file == '\\') || (file[1] == ':') /* Absolute path (DOS) */
     684             : #else /* ifndef _WIN32 */
     685      211369 :       || (*file == '/') /* Absolute path (U*ix) */
     686             : #endif /* ifndef _WIN32 */
     687             :       )
     688             :    {
     689       30980 :       return strdup(file);
     690             :    }
     691             :    else
     692             :    {
     693             :       char * path;
     694      211369 :       size_t path_size = strlen(dir) + strlen(file) + 2; /* +2 for trailing (back)slash and \0 */
     695             : 
     696             : #if defined(unix)
     697      211369 :       if (*dir != '/' && basedir && *basedir)
     698             :       {
     699             :          /*
     700             :           * Relative path, so start with the base directory.
     701             :           */
     702      107543 :          path_size += strlen(basedir) + 1; /* +1 for the slash */
     703      107543 :          path = malloc(path_size);
     704      107543 :          if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!");
     705      107543 :          strlcpy(path, basedir, path_size);
     706      107543 :          strlcat(path, "/", path_size);
     707      107543 :          strlcat(path, dir, path_size);
     708             :       }
     709             :       else
     710             : #endif /* defined unix */
     711             :       {
     712      103826 :          path = malloc(path_size);
     713      103826 :          if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!");
     714      103826 :          strlcpy(path, dir, path_size);
     715             :       }
     716             : 
     717      211369 :       assert(NULL != path);
     718             : #if defined(_WIN32)
     719             :       if (path[strlen(path)-1] != '\\')
     720             :       {
     721             :          strlcat(path, "\\", path_size);
     722             :       }
     723             : #else /* ifndef _WIN32 */
     724      211369 :       if (path[strlen(path)-1] != '/')
     725             :       {
     726      201740 :          strlcat(path, "/", path_size);
     727             :       }
     728             : #endif /* ifndef _WIN32 */
     729      211369 :       strlcat(path, file, path_size);
     730             : 
     731      211369 :       return path;
     732             :    }
     733             : }
     734             : 
     735             : 
     736             : /*********************************************************************
     737             :  *
     738             :  * Function    :  pick_from_range
     739             :  *
     740             :  * Description :  Pick a positive number out of a given range.
     741             :  *                Should only be used if randomness would be nice,
     742             :  *                but isn't really necessary.
     743             :  *
     744             :  * Parameters  :
     745             :  *          1  :  range: Highest possible number to pick.
     746             :  *
     747             :  * Returns     :  Picked number.
     748             :  *
     749             :  *********************************************************************/
     750         918 : long int pick_from_range(long int range)
     751             : {
     752             :    long int number;
     753             : #ifdef _WIN32
     754             :    static unsigned long seed = 0;
     755             : #endif /* def _WIN32 */
     756             : 
     757         918 :    assert(range != 0);
     758         918 :    assert(range > 0);
     759             : 
     760         918 :    if (range <= 0) return 0;
     761             : 
     762             : #ifdef HAVE_ARC4RANDOM
     763             :    number = arc4random() % range + 1;
     764             : #elif defined(HAVE_RANDOM)
     765         918 :    number = random() % range + 1;
     766             : #elif defined(MUTEX_LOCKS_AVAILABLE)
     767             :    privoxy_mutex_lock(&rand_mutex);
     768             : #ifdef _WIN32
     769             :    if (!seed)
     770             :    {
     771             :       seed = (unsigned long)(GetCurrentThreadId()+GetTickCount());
     772             :    }
     773             :    srand(seed);
     774             :    seed = (unsigned long)((rand() << 16) + rand());
     775             : #endif /* def _WIN32 */
     776             :    number = (unsigned long)((rand() << 16) + (rand())) % (unsigned long)(range + 1);
     777             :    privoxy_mutex_unlock(&rand_mutex);
     778             : #else
     779             :    /*
     780             :     * XXX: Which platforms reach this and are there
     781             :     * better options than just using rand() and hoping
     782             :     * that it's safe?
     783             :     */
     784             :    log_error(LOG_LEVEL_INFO, "No thread-safe PRNG available? Header time randomization "
     785             :       "might cause crashes, predictable results or even combine these fine options.");
     786             :    number = rand() % (long int)(range + 1);
     787             : 
     788             : #endif /* (def HAVE_ARC4RANDOM) */
     789             : 
     790         918 :    return number;
     791             : }
     792             : 
     793             : 
     794             : #ifdef USE_PRIVOXY_STRLCPY
     795             : /*********************************************************************
     796             :  *
     797             :  * Function    :  privoxy_strlcpy
     798             :  *
     799             :  * Description :  strlcpy(3) look-alike for those without decent libc.
     800             :  *
     801             :  * Parameters  :
     802             :  *          1  :  destination: buffer to copy into.
     803             :  *          2  :  source: String to copy.
     804             :  *          3  :  size: Size of destination buffer.
     805             :  *
     806             :  * Returns     :  The length of the string that privoxy_strlcpy() tried to create.
     807             :  *
     808             :  *********************************************************************/
     809    27003053 : size_t privoxy_strlcpy(char *destination, const char *source, const size_t size)
     810             : {
     811    27003053 :    if (0 < size)
     812             :    {
     813    27003053 :       snprintf(destination, size, "%s", source);
     814             :       /*
     815             :        * Platforms that lack strlcpy() also tend to have
     816             :        * a broken snprintf implementation that doesn't
     817             :        * guarantee nul termination.
     818             :        *
     819             :        * XXX: the configure script should detect and reject those.
     820             :        */
     821    27003053 :       destination[size-1] = '\0';
     822             :    }
     823    27003053 :    return strlen(source);
     824             : }
     825             : #endif /* def USE_PRIVOXY_STRLCPY */
     826             : 
     827             : 
     828             : #ifndef HAVE_STRLCAT
     829             : /*********************************************************************
     830             :  *
     831             :  * Function    :  privoxy_strlcat
     832             :  *
     833             :  * Description :  strlcat(3) look-alike for those without decent libc.
     834             :  *
     835             :  * Parameters  :
     836             :  *          1  :  destination: C string.
     837             :  *          2  :  source: String to copy.
     838             :  *          3  :  size: Size of destination buffer.
     839             :  *
     840             :  * Returns     :  The length of the string that privoxy_strlcat() tried to create.
     841             :  *
     842             :  *********************************************************************/
     843      635345 : size_t privoxy_strlcat(char *destination, const char *source, const size_t size)
     844             : {
     845      635345 :    const size_t old_length = strlen(destination);
     846      635345 :    return old_length + strlcpy(destination + old_length, source, size - old_length);
     847             : }
     848             : #endif /* ndef HAVE_STRLCAT */
     849             : 
     850             : 
     851             : /*********************************************************************
     852             :  *
     853             :  * Function    :  privoxy_millisleep
     854             :  *
     855             :  * Description :  Sleep a number of milliseconds
     856             :  *
     857             :  * Parameters  :
     858             :  *          1  :  delay: Number of milliseconds to sleep
     859             :  *
     860             :  * Returns     :  -1 on error, 0 otherwise
     861             :  *
     862             :  *********************************************************************/
     863           0 : int privoxy_millisleep(unsigned milliseconds)
     864             : {
     865             : #ifdef HAVE_NANOSLEEP
     866           0 :    struct timespec rqtp = {0};
     867           0 :    struct timespec rmtp = {0};
     868             : 
     869           0 :    rqtp.tv_sec = milliseconds / 1000;
     870           0 :    rqtp.tv_nsec = (milliseconds % 1000) * 1000 * 1000;
     871             : 
     872           0 :    return nanosleep(&rqtp, &rmtp);
     873             : #elif defined (_WIN32)
     874             :    Sleep(milliseconds);
     875             : 
     876             :    return 0;
     877             : #else
     878             : #warning Missing privoxy_milisleep() implementation. delay-response{} will not work.
     879             : 
     880             :    return -1;
     881             : #endif /* def HAVE_NANOSLEEP */
     882             : 
     883             : }
     884             : 
     885             : 
     886             : /*********************************************************************
     887             :  *
     888             :  * Function    :  privoxy_gmtime_r
     889             :  *
     890             :  * Description :  Behave like gmtime_r() and convert a
     891             :  *                time_t to a struct tm.
     892             :  *
     893             :  * Parameters  :
     894             :  *          1  :  time_spec: The time to convert
     895             :  *          2  :  result: The struct tm to use as storage
     896             :  *
     897             :  * Returns     :  Pointer to the result or NULL on error.
     898             :  *
     899             :  *********************************************************************/
     900        2382 : struct tm *privoxy_gmtime_r(const time_t *time_spec, struct tm *result)
     901             : {
     902             :    struct tm *timeptr;
     903             : 
     904             : #ifdef HAVE_GMTIME_R
     905        2382 :    timeptr = gmtime_r(time_spec, result);
     906             : #elif defined(MUTEX_LOCKS_AVAILABLE)
     907             :    privoxy_mutex_lock(&gmtime_mutex);
     908             :    timeptr = gmtime(time_spec);
     909             : #else
     910             : #warning Using unlocked gmtime()
     911             :    timeptr = gmtime(time_spec);
     912             : #endif
     913             : 
     914        2382 :    if (timeptr == NULL)
     915             :    {
     916             : #if !defined(HAVE_GMTIME_R) && defined(MUTEX_LOCKS_AVAILABLE)
     917             :       privoxy_mutex_unlock(&gmtime_mutex);
     918             : #endif
     919           0 :       return NULL;
     920             :    }
     921             : 
     922             : #if !defined(HAVE_GMTIME_R)
     923             :    *result = *timeptr;
     924             :    timeptr = result;
     925             : #ifdef MUTEX_LOCKS_AVAILABLE
     926             :    privoxy_mutex_unlock(&gmtime_mutex);
     927             : #endif
     928             : #endif
     929             : 
     930        2382 :    return timeptr;
     931             : }
     932             : 
     933             : #if !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV)
     934             : /*********************************************************************
     935             :  *
     936             :  * Function    :  timegm
     937             :  *
     938             :  * Description :  libc replacement function for the inverse of gmtime().
     939             :  *                Copyright (C) 2004 Free Software Foundation, Inc.
     940             :  *
     941             :  *                Code originally copied from GnuPG, modifications done
     942             :  *                for Privoxy: style changed, #ifdefs for _WIN32 added
     943             :  *                to have it work on mingw32.
     944             :  *
     945             :  *                XXX: It's very unlikely to happen, but if the malloc()
     946             :  *                call fails the time zone will be permanently set to UTC.
     947             :  *
     948             :  * Parameters  :
     949             :  *          1  :  tm: Broken-down time struct.
     950             :  *
     951             :  * Returns     :  tm converted into time_t seconds.
     952             :  *
     953             :  *********************************************************************/
     954             : time_t timegm(struct tm *tm)
     955             : {
     956             :    time_t answer;
     957             :    char *zone;
     958             : 
     959             :    zone = getenv("TZ");
     960             :    putenv("TZ=UTC");
     961             :    tzset();
     962             :    answer = mktime(tm);
     963             :    if (zone)
     964             :    {
     965             :       char *old_zone;
     966             : 
     967             :       old_zone = malloc(3 + strlen(zone) + 1);
     968             :       if (old_zone)
     969             :       {
     970             :          strcpy(old_zone, "TZ=");
     971             :          strcat(old_zone, zone);
     972             :          putenv(old_zone);
     973             : #ifdef _WIN32
     974             :          /* http://man7.org/linux/man-pages/man3/putenv.3.html
     975             :           *   int putenv(char *string);
     976             :           *     The string pointed to by string becomes part of the environment, so altering the
     977             :           *     string changes the environment.
     978             :           * In other words, the memory pointed to by *string is used until
     979             :           *   a) another call to putenv() with the same e-var name
     980             :           *   b) the program exits
     981             :           *
     982             :           * Windows e-vars don't work that way, so let's not leak memory.
     983             :           */
     984             :          free(old_zone);
     985             : #endif /* def _WIN32 */
     986             :       }
     987             :    }
     988             :    else
     989             :    {
     990             : #ifdef HAVE_UNSETENV
     991             :       unsetenv("TZ");
     992             : #elif defined(_WIN32)
     993             :       putenv("TZ=");
     994             : #else
     995             :       putenv("TZ");
     996             : #endif
     997             :    }
     998             :    tzset();
     999             : 
    1000             :    return answer;
    1001             : }
    1002             : #endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
    1003             : 
    1004             : 
    1005             : /*
    1006             :   Local Variables:
    1007             :   tab-width: 3
    1008             :   end:
    1009             : */

Generated by: LCOV version 1.14