Changeset 3356


Ignore:
Timestamp:
Oct 26, 2010 11:53:28 PM (13 years ago)
Author:
bennylp
Message:

Fixed #1152 (The base64 decoder should ignore whitespaces in the input). In fact, the base64 decoder now will silently ignore/skip any bad characters.

Location:
pjproject/trunk/pjlib-util/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/src/pjlib-util-test/encryption.c

    r2690 r3356  
    495495} 
    496496 
     497enum 
     498{ 
     499    ENCODE = 1, 
     500    DECODE = 2, 
     501    ENCODE_DECODE = 3 
     502}; 
    497503 
    498504/* 
     
    503509    const char *base256; 
    504510    const char *base64; 
     511    unsigned flag; 
    505512} base64_test_vec[] =  
    506513{ 
    507514    { 
    508515        "", 
    509         "" 
     516        "", 
     517        ENCODE_DECODE 
    510518    }, 
    511519    { 
    512520        "f", 
    513         "Zg==" 
     521        "Zg==", 
     522        ENCODE_DECODE 
    514523    }, 
    515524    { 
    516525        "fo", 
    517         "Zm8=" 
     526        "Zm8=", 
     527        ENCODE_DECODE 
    518528    }, 
    519529    { 
    520530        "foo", 
    521         "Zm9v" 
     531        "Zm9v", 
     532        ENCODE_DECODE 
    522533    }, 
    523534    { 
    524535        "foob", 
    525         "Zm9vYg==" 
     536        "Zm9vYg==", 
     537        ENCODE_DECODE 
    526538    }, 
    527539    { 
    528540        "fooba", 
    529541        "Zm9vYmE=", 
     542        ENCODE_DECODE 
    530543    }, 
    531544    { 
    532545        "foobar", 
    533         "Zm9vYmFy" 
     546        "Zm9vYmFy", 
     547        ENCODE_DECODE 
    534548    }, 
    535549    { 
    536550        "\x14\xfb\x9c\x03\xd9\x7e", 
    537         "FPucA9l+" 
     551        "FPucA9l+", 
     552        ENCODE_DECODE 
    538553    }, 
    539554    { 
    540555        "\x14\xfb\x9c\x03\xd9", 
    541         "FPucA9k=" 
     556        "FPucA9k=", 
     557        ENCODE_DECODE 
    542558    }, 
    543559    { 
    544560        "\x14\xfb\x9c\x03", 
    545         "FPucAw==" 
    546     } 
     561        "FPucAw==", 
     562        ENCODE_DECODE 
     563    }, 
     564    /* with whitespaces */ 
     565    { 
     566        "foobar", 
     567        "Zm9v\r\nYmFy", 
     568        DECODE 
     569    }, 
     570    { 
     571        "foobar", 
     572        "\nZ\r\nm 9\tv\nYm\nF\ny\n", 
     573        DECODE 
     574    }, 
    547575}; 
    548576 
     
    557585 
    558586    for (i=0; i<PJ_ARRAY_SIZE(base64_test_vec); ++i) { 
     587        pj_str_t input; 
     588        int out_len; 
     589 
    559590        /* Encode test */ 
    560         pj_str_t input; 
    561         int out_len = sizeof(output); 
    562  
    563         rc = pj_base64_encode((pj_uint8_t*)base64_test_vec[i].base256,  
    564                               strlen(base64_test_vec[i].base256), 
    565                               output, &out_len); 
    566         if (rc != PJ_SUCCESS) 
    567             return -90; 
    568  
    569         if (out_len != (int)strlen(base64_test_vec[i].base64)) 
    570             return -91; 
    571  
    572         output[out_len] = '\0'; 
    573         if (strcmp(output, base64_test_vec[i].base64) != 0) 
    574             return -92; 
     591        if (base64_test_vec[i].flag & ENCODE) { 
     592            out_len = sizeof(output); 
     593            rc = pj_base64_encode((pj_uint8_t*)base64_test_vec[i].base256, 
     594                                  strlen(base64_test_vec[i].base256), 
     595                                  output, &out_len); 
     596            if (rc != PJ_SUCCESS) 
     597                return -90; 
     598 
     599            if (out_len != (int)strlen(base64_test_vec[i].base64)) 
     600                return -91; 
     601 
     602            output[out_len] = '\0'; 
     603            if (strcmp(output, base64_test_vec[i].base64) != 0) 
     604                return -92; 
     605        } 
    575606 
    576607        /* Decode test */ 
    577         out_len = sizeof(output); 
    578         input.ptr = (char*)base64_test_vec[i].base64; 
    579         input.slen = strlen(base64_test_vec[i].base64); 
    580         rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len); 
    581         if (rc != PJ_SUCCESS) 
    582             return -95; 
    583  
    584         if (out_len != (int)strlen(base64_test_vec[i].base256)) 
    585             return -96; 
    586  
    587         output[out_len] = '\0'; 
    588  
    589         if (strcmp(output, base64_test_vec[i].base256) != 0) 
    590             return -97; 
     608        if (base64_test_vec[i].flag & DECODE) { 
     609            out_len = sizeof(output); 
     610            input.ptr = (char*)base64_test_vec[i].base64; 
     611            input.slen = strlen(base64_test_vec[i].base64); 
     612            rc = pj_base64_decode(&input, (pj_uint8_t*)output, &out_len); 
     613            if (rc != PJ_SUCCESS) 
     614                return -95; 
     615 
     616            if (out_len != (int)strlen(base64_test_vec[i].base256)) 
     617                return -96; 
     618 
     619            output[out_len] = '\0'; 
     620 
     621            if (strcmp(output, base64_test_vec[i].base256) != 0) 
     622                return -97; 
     623        } 
    591624    } 
    592625 
  • pjproject/trunk/pjlib-util/src/pjlib-util/base64.c

    r2394 r3356  
    4848        return (63); 
    4949    else { 
    50         pj_assert(!"Should not happen as '=' should have been filtered"); 
     50        /* It *may* happen on bad input, so this is not a good idea. 
     51         * pj_assert(!"Should not happen as '=' should have been filtered"); 
     52         */ 
    5153        return INV; 
    5254    } 
     
    125127    const char *buf = input->ptr; 
    126128    int len = input->slen; 
    127     int i, j; 
    128     int c1, c2, c3, c4; 
     129    int i, j, k; 
     130    int c[4]; 
    129131 
    130132    PJ_ASSERT_RETURN(input && out && out_len, PJ_EINVAL); 
     
    136138                     PJ_ETOOSMALL); 
    137139 
    138     for (i=0, j=0; i+3 < len; i+=4) { 
    139         c1 = base256_char(buf[i]); 
    140         c2 = base256_char(buf[i+1]); 
    141         c3 = base256_char(buf[i+2]); 
    142         c4 = base256_char(buf[i+3]); 
     140    for (i=0, j=0; i<len; ) { 
     141        /* Fill up c, silently ignoring invalid characters */ 
     142        for (k=0; k<4 && i<len; ++k) { 
     143            do { 
     144                c[k] = base256_char(buf[i++]); 
     145            } while (c[k]==INV && i<len); 
     146        } 
    143147 
    144         out[j++] = (pj_uint8_t)((c1<<2) | ((c2 & 0x30)>>4)); 
    145         out[j++] = (pj_uint8_t)(((c2 & 0x0F)<<4) | ((c3 & 0x3C)>>2)); 
    146         out[j++] = (pj_uint8_t)(((c3 & 0x03)<<6) | (c4 & 0x3F)); 
    147     } 
    148  
    149     if (i < len) { 
    150         c1 = base256_char(buf[i]); 
    151  
    152         if (i+1 < len) 
    153             c2 = base256_char(buf[i+1]); 
    154         else  
    155             c2 = (INV); 
    156  
    157         if (i+2 < len) 
    158             c3 = base256_char(buf[i+2]); 
    159         else 
    160             c3 = (INV); 
    161  
    162         c4 = (INV); 
    163  
    164         if (c2 != INV) { 
    165             out[j++] = (pj_uint8_t)((c1<<2) | ((c2 & 0x30)>>4)); 
    166             if (c3 != INV) { 
    167                 out[j++] = (pj_uint8_t)(((c2 & 0x0F)<<4) | ((c3 & 0x3C)>>2)); 
    168                 if (c4 != INV) { 
    169                     out[j++] = (pj_uint8_t)(((c3 & 0x03)<<6) | (c4 & 0x3F)); 
     148        if (k<4) { 
     149            if (k > 1) { 
     150                out[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4)); 
     151                if (k > 2) { 
     152                    out[j++] = (pj_uint8_t) 
     153                               (((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2)); 
    170154                } 
    171155            } 
     156            break; 
    172157        } 
    173          
     158 
     159        out[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4)); 
     160        out[j++] = (pj_uint8_t)(((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2)); 
     161        out[j++] = (pj_uint8_t)(((c[2] & 0x03)<<6) | (c[3] & 0x3F)); 
    174162    } 
    175163 
Note: See TracChangeset for help on using the changeset viewer.