~ubuntu-branches/ubuntu/raring/clamav/raring

« back to all changes in this revision

Viewing changes to libclamav/str.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen Gran
  • Date: 2008-09-05 17:25:34 UTC
  • mfrom: (0.35.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080905172534-yi3f8fkye1o7u1r3
* New upstream version (closes: #497662, #497773)
  - lots of new options for clamd.conf
  - fixes CVEs CVE-2008-3912, CVE-2008-3913, CVE-2008-3914, and
    CVE-2008-1389
* No longer supports --unzip option, so typo is gone (closes: #496276)
* Translations:
  - sv (thanks Martin Bagge <brother@bsnet.se>) (closes: #491760)

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include "others.h"
35
35
#include "matcher.h"
36
36
#include "cltypes.h"
37
 
 
38
 
static int cli_hex2int(int c)
 
37
#include "jsparse/textbuf.h"
 
38
 
 
39
static const int hex_chars[256] = {
 
40
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
41
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
42
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
43
     0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
 
44
    -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
45
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
46
    -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
47
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
48
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
49
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
50
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
51
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
52
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
53
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
54
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
55
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
 
56
};
 
57
 
 
58
static inline int cli_hex2int(const char c)
39
59
{
40
 
        int l;
41
 
 
42
 
    if(!isascii(c))
43
 
        return -1;
44
 
 
45
 
    if(isdigit(c))
46
 
        return c - '0';
47
 
 
48
 
    l = tolower(c);
49
 
    if((l >= 'a') && (l <= 'f'))
50
 
        return l + 10 - 'a';
51
 
 
52
 
    cli_errmsg("hex2int() translation problem (%d)\n", l);
53
 
    return -1;
 
60
        return hex_chars[(const unsigned char)c];
54
61
}
55
62
 
56
63
uint16_t *cli_hex2ui(const char *hex)
123
130
 
124
131
char *cli_hex2str(const char *hex)
125
132
{
126
 
        char *str, *ptr, val, c;
127
 
        int i, len;
 
133
        char *str, *ptr;
 
134
        int i, len, val, c;
128
135
 
129
136
 
130
137
    len = strlen(hex);
154
161
            return NULL;
155
162
        }
156
163
 
157
 
        *ptr++ = val;
 
164
        *ptr++ = (char)val;
158
165
    }
159
166
 
160
167
    return str;
442
449
 
443
450
    return 1;
444
451
}
 
452
 
 
453
/* encodes the unicode character as utf-8 */
 
454
static inline size_t output_utf8(uint16_t u, unsigned char* dst)
 
455
{
 
456
        if(!u) {
 
457
                *dst = 0x1; /* don't add \0, add \1 instead */
 
458
                return 1;
 
459
        }
 
460
        if(u < 0x80) {
 
461
                *dst = u&0xff;
 
462
                return 1;
 
463
        }
 
464
        if(u < 0x800) {
 
465
                *dst++ = 0xc0 | (u>>6);   /* 110yyyyy */
 
466
                *dst = 0x80 | (u & 0x3f); /* 10zzzzzz */
 
467
                return 2;
 
468
        }
 
469
        /* u < 0x10000 because we only handle utf-16,
 
470
         * values in range 0xd800 - 0xdfff aren't valid, but we don't check for
 
471
         * that*/
 
472
        *dst++ = 0xe0 | (u>>12);        /* 1110xxxx */
 
473
        *dst++ = 0x80 | ((u>>6)&0x3f); /* 10yyyyyy */
 
474
        *dst = 0x80 | (u & 0x3f);      /* 10zzzzzz */
 
475
        return 3;
 
476
}
 
477
 
 
478
/* javascript-like unescape() function */
 
479
char *cli_unescape(const char *str)
 
480
{
 
481
        char *R;
 
482
        size_t k, i=0;
 
483
        const size_t len = strlen(str);
 
484
        /* unescaped string is at most as long as original,
 
485
         * it will usually be shorter */
 
486
        R = cli_malloc(len + 1);
 
487
        if(!R)
 
488
                return NULL;
 
489
        for(k=0;k < len;k++) {
 
490
                unsigned char c = str[k];
 
491
                if (str[k] == '%') {
 
492
                        if(k+5 >= len || str[k+1] != 'u' || !isxdigit(str[k+2]) || !isxdigit(str[k+3])
 
493
                                                || !isxdigit(str[k+4]) || !isxdigit(str[k+5])) {
 
494
                                if(k+2 < len && isxdigit(str[k+1]) && isxdigit(str[k+2])) {
 
495
                                        c = (cli_hex2int(str[k+1])<<4) | cli_hex2int(str[k+2]);
 
496
                                        k += 2;
 
497
                                }
 
498
                        } else {
 
499
                                uint16_t u = (cli_hex2int(str[k+2])<<12) | (cli_hex2int(str[k+3])<<8) |
 
500
                                        (cli_hex2int(str[k+4])<<4) | cli_hex2int(str[k+5]);
 
501
                                i += output_utf8(u, (unsigned char*)&R[i]);
 
502
                                k += 5;
 
503
                                continue;
 
504
                        }
 
505
                }
 
506
                if(!c) c = 1; /* don't add \0 */
 
507
                R[i++] = c;
 
508
        }
 
509
        R[i++] = '\0';
 
510
        R = cli_realloc2(R, i);
 
511
        return R;
 
512
}
 
513
 
 
514
/* handle javascript's escape sequences inside strings */
 
515
int cli_textbuffer_append_normalize(struct text_buffer *buf, const char *str, size_t len)
 
516
{
 
517
        size_t i;
 
518
        for(i=0;i < len;i++) {
 
519
                char c = str[i];
 
520
                if (c == '\\' && i+1 < len) {
 
521
                        i++;
 
522
                        switch (str[i]) {
 
523
                                case '0':
 
524
                                        c = 0;
 
525
                                        break;
 
526
                                case 'b':
 
527
                                        c = 8;
 
528
                                        break;
 
529
                                case 't':
 
530
                                        c = 9;
 
531
                                        break;
 
532
                                case 'n':
 
533
                                        c = 10;
 
534
                                        break;
 
535
                                case 'v':
 
536
                                        c = 11;
 
537
                                        break;
 
538
                                case 'f':
 
539
                                        c = 12;
 
540
                                        break;
 
541
                                case 'r':
 
542
                                        c=13;
 
543
                                        break;
 
544
                                case 'x':
 
545
                                        if(i+2 < len)
 
546
                                                c = (cli_hex2int(str[i+1])<<4)|cli_hex2int(str[i+2]);
 
547
                                        i += 2;
 
548
                                        break;
 
549
                                case 'u':
 
550
                                        if(i+4 < len) {
 
551
                                                uint16_t u = (cli_hex2int(str[i+1])<<12) | (cli_hex2int(str[i+2])<<8) |
 
552
                                                        (cli_hex2int(str[i+3])<<4) | cli_hex2int(str[i+4]);
 
553
                                                if(textbuffer_ensure_capacity(buf, 4) == -1)
 
554
                                                        return -1;
 
555
                                                buf->pos += output_utf8(u, (unsigned char*)&buf->data[buf->pos]);
 
556
                                                i += 4;
 
557
                                                continue;
 
558
                                        }
 
559
                                        break;
 
560
                                default:
 
561
                                        c = str[i];
 
562
                                        break;
 
563
                        }
 
564
                }
 
565
                if(!c) c = 1; /* we don't insert \0 */
 
566
                if(textbuffer_putc(buf, c) == -1)
 
567
                        return -1;
 
568
        }
 
569
        return 0;
 
570
}
 
571