Ignore:
Timestamp:
Nov 8, 2017 2:58:18 AM (5 years ago)
Author:
riza
Message:

Closed #2056: Add validity checking for numeric header values.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/src/pj/string.c

    r5520 r5682  
    2424#include <pj/rand.h> 
    2525#include <pj/os.h> 
     26#include <pj/errno.h> 
     27#include <pj/limits.h> 
    2628 
    2729#if PJ_FUNCTIONS_ARE_INLINED==0 
    2830#  include <pj/string_i.h> 
    2931#endif 
     32 
    3033 
    3134PJ_DEF(pj_ssize_t) pj_strspn(const pj_str_t *str, const pj_str_t *set_char) 
     
    231234} 
    232235 
     236 
     237PJ_DEF(pj_status_t) pj_strtol2(const pj_str_t *str, long *value) 
     238{ 
     239    pj_str_t s; 
     240    unsigned long retval = 0; 
     241    pj_bool_t is_negative = PJ_FALSE; 
     242    int rc = 0; 
     243 
     244    PJ_CHECK_STACK(); 
     245 
     246    if (!str || !value) { 
     247        return PJ_EINVAL; 
     248    } 
     249 
     250    s = *str; 
     251    pj_strltrim(&s); 
     252 
     253    if (s.slen == 0) 
     254        return PJ_EINVAL; 
     255 
     256    if (s.ptr[0] == '+' || s.ptr[0] == '-') { 
     257        is_negative = (s.ptr[0] == '-'); 
     258        s.ptr += 1; 
     259        s.slen -= 1; 
     260    } 
     261 
     262    rc = pj_strtoul3(&s, &retval, 10); 
     263    if (rc == PJ_EINVAL) { 
     264        return rc; 
     265    } else if (rc != PJ_SUCCESS) { 
     266        *value = is_negative ? PJ_MINLONG : PJ_MAXLONG; 
     267        return is_negative ? PJ_ETOOSMALL : PJ_ETOOBIG; 
     268    } 
     269 
     270    if (retval > PJ_MAXLONG && !is_negative) { 
     271        *value = PJ_MAXLONG; 
     272        return PJ_ETOOBIG; 
     273    } 
     274 
     275    if (retval > (PJ_MAXLONG + 1UL) && is_negative) { 
     276        *value = PJ_MINLONG; 
     277        return PJ_ETOOSMALL; 
     278    } 
     279 
     280    *value = is_negative ? -(long)retval : retval; 
     281 
     282    return PJ_SUCCESS; 
     283} 
     284 
    233285PJ_DEF(unsigned long) pj_strtoul(const pj_str_t *str) 
    234286{ 
     
    281333 
    282334    return value; 
     335} 
     336 
     337PJ_DEF(pj_status_t) pj_strtoul3(const pj_str_t *str, unsigned long *value, 
     338                                unsigned base) 
     339{ 
     340    pj_str_t s; 
     341    unsigned i; 
     342 
     343    PJ_CHECK_STACK(); 
     344 
     345    if (!str || !value) { 
     346        return PJ_EINVAL; 
     347    } 
     348 
     349    s = *str; 
     350    pj_strltrim(&s); 
     351 
     352    if (s.slen == 0 || s.ptr[0] < '0' || 
     353        (base <= 10 && (unsigned)s.ptr[0] > ('0' - 1) + base) || 
     354        (base == 16 && !pj_isxdigit(s.ptr[0]))) 
     355    { 
     356        return PJ_EINVAL; 
     357    } 
     358 
     359    *value = 0; 
     360    if (base <= 10) { 
     361        for (i=0; i<(unsigned)s.slen; ++i) { 
     362            unsigned c = s.ptr[i] - '0'; 
     363            if (s.ptr[i] < '0' || (unsigned)s.ptr[i] > ('0' - 1) + base) { 
     364                break; 
     365            } 
     366            if (*value > PJ_MAXULONG / base) { 
     367                *value = PJ_MAXULONG; 
     368                return PJ_ETOOBIG; 
     369            } 
     370 
     371            *value *= base; 
     372            if ((PJ_MAXULONG - *value) < c) { 
     373                *value = PJ_MAXULONG; 
     374                return PJ_ETOOBIG; 
     375            } 
     376            *value += c; 
     377        } 
     378    } else if (base == 16) { 
     379        for (i=0; i<(unsigned)s.slen; ++i) { 
     380            unsigned c = pj_hex_digit_to_val(s.ptr[i]); 
     381            if (!pj_isxdigit(s.ptr[i])) 
     382                break; 
     383 
     384            if (*value > PJ_MAXULONG / base) { 
     385                *value = PJ_MAXULONG; 
     386                return PJ_ETOOBIG; 
     387            } 
     388            *value *= base; 
     389            if ((PJ_MAXULONG - *value) < c) { 
     390                *value = PJ_MAXULONG; 
     391                return PJ_ETOOBIG; 
     392            } 
     393            *value += c; 
     394        } 
     395    } else { 
     396        pj_assert(!"Unsupported base"); 
     397        return PJ_EINVAL; 
     398    } 
     399    return PJ_SUCCESS; 
    283400} 
    284401 
     
    357474    return len; 
    358475} 
    359  
    360  
Note: See TracChangeset for help on using the changeset viewer.