Blame dwarfdump/uri.c

Packit cdaae3
/*
Packit cdaae3
    Copyright 2011-2012 David Anderson. All rights reserved.
Packit cdaae3
    Portions Copyright 2012 SN Systems Ltd. All rights reserved.
Packit cdaae3
Packit cdaae3
    This program is free software; you can redistribute it and/or modify it
Packit cdaae3
    under the terms of version 2 of the GNU General Public License as
Packit cdaae3
    published by the Free Software Foundation.
Packit cdaae3
Packit cdaae3
    This program is distributed in the hope that it would be useful, but
Packit cdaae3
    WITHOUT ANY WARRANTY; without even the implied warranty of
Packit cdaae3
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Packit cdaae3
Packit cdaae3
    Further, this software is distributed without any warranty that it is
Packit cdaae3
    free of the rightful claim of any third person regarding infringement
Packit cdaae3
    or the like.  Any license provided herein, whether implied or
Packit cdaae3
    otherwise, applies only to this software file.  Patent licenses, if
Packit cdaae3
    any, provided herein do not apply to combinations of this program with
Packit cdaae3
    other software, or any other product whatsoever.
Packit cdaae3
Packit cdaae3
    You should have received a copy of the GNU General Public License along
Packit cdaae3
    with this program; if not, write the Free Software Foundation, Inc., 51
Packit cdaae3
    Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
Packit cdaae3
Packit cdaae3
*/
Packit cdaae3
Packit cdaae3
#include "globals.h"
Packit cdaae3
#include "esb.h"
Packit cdaae3
#include "uri.h"
Packit cdaae3
#include <stdio.h>
Packit cdaae3
#include <ctype.h>
Packit cdaae3
Packit cdaae3
/* dwarfdump_ctype table. See uritablebuild.c */
Packit cdaae3
static char dwarfdump_ctype_table[256] = {
Packit cdaae3
0, /* NUL 0x00 */
Packit cdaae3
0, /* control 0x01 */
Packit cdaae3
0, /* control 0x02 */
Packit cdaae3
0, /* control 0x03 */
Packit cdaae3
0, /* control 0x04 */
Packit cdaae3
0, /* control 0x05 */
Packit cdaae3
0, /* control 0x06 */
Packit cdaae3
0, /* control 0x07 */
Packit cdaae3
0, /* control 0x08 */
Packit cdaae3
0, /* whitespace 0x09 */
Packit cdaae3
0, /* whitespace 0x0a */
Packit cdaae3
0, /* whitespace 0x0b */
Packit cdaae3
0, /* whitespace 0x0c */
Packit cdaae3
0, /* whitespace 0x0d */
Packit cdaae3
0, /* control 0x0e */
Packit cdaae3
0, /* control 0x0f */
Packit cdaae3
0, /* control 0x10 */
Packit cdaae3
0, /* control 0x11 */
Packit cdaae3
0, /* control 0x12 */
Packit cdaae3
0, /* control 0x13 */
Packit cdaae3
0, /* control 0x14 */
Packit cdaae3
0, /* control 0x15 */
Packit cdaae3
0, /* control 0x16 */
Packit cdaae3
0, /* control 0x17 */
Packit cdaae3
0, /* control 0x18 */
Packit cdaae3
0, /* control 0x19 */
Packit cdaae3
0, /* control 0x1a */
Packit cdaae3
0, /* control 0x1b */
Packit cdaae3
0, /* control 0x1c */
Packit cdaae3
0, /* control 0x1d */
Packit cdaae3
0, /* control 0x1e */
Packit cdaae3
0, /* control 0x1f */
Packit cdaae3
1, /* ' ' 0x20 */
Packit cdaae3
1, /* '!' 0x21 */
Packit cdaae3
0, /* '"' 0x22 */
Packit cdaae3
1, /* '#' 0x23 */
Packit cdaae3
1, /* '$' 0x24 */
Packit cdaae3
0, /* '%' 0x25 */
Packit cdaae3
1, /* '&' 0x26 */
Packit cdaae3
0, /* ''' 0x27 */
Packit cdaae3
1, /* '(' 0x28 */
Packit cdaae3
1, /* ')' 0x29 */
Packit cdaae3
1, /* '*' 0x2a */
Packit cdaae3
1, /* '+' 0x2b */
Packit cdaae3
1, /* ',' 0x2c */
Packit cdaae3
1, /* '-' 0x2d */
Packit cdaae3
1, /* '.' 0x2e */
Packit cdaae3
1, /* '/' 0x2f */
Packit cdaae3
1, /* '0' 0x30 */
Packit cdaae3
1, /* '1' 0x31 */
Packit cdaae3
1, /* '2' 0x32 */
Packit cdaae3
1, /* '3' 0x33 */
Packit cdaae3
1, /* '4' 0x34 */
Packit cdaae3
1, /* '5' 0x35 */
Packit cdaae3
1, /* '6' 0x36 */
Packit cdaae3
1, /* '7' 0x37 */
Packit cdaae3
1, /* '8' 0x38 */
Packit cdaae3
1, /* '9' 0x39 */
Packit cdaae3
1, /* ':' 0x3a */
Packit cdaae3
0, /* ';' 0x3b */
Packit cdaae3
1, /* '<' 0x3c */
Packit cdaae3
1, /* '=' 0x3d */
Packit cdaae3
1, /* '>' 0x3e */
Packit cdaae3
1, /* '?' 0x3f */
Packit cdaae3
1, /* '@' 0x40 */
Packit cdaae3
1, /* 'A' 0x41 */
Packit cdaae3
1, /* 'B' 0x42 */
Packit cdaae3
1, /* 'C' 0x43 */
Packit cdaae3
1, /* 'D' 0x44 */
Packit cdaae3
1, /* 'E' 0x45 */
Packit cdaae3
1, /* 'F' 0x46 */
Packit cdaae3
1, /* 'G' 0x47 */
Packit cdaae3
1, /* 'H' 0x48 */
Packit cdaae3
1, /* 'I' 0x49 */
Packit cdaae3
1, /* 'J' 0x4a */
Packit cdaae3
1, /* 'K' 0x4b */
Packit cdaae3
1, /* 'L' 0x4c */
Packit cdaae3
1, /* 'M' 0x4d */
Packit cdaae3
1, /* 'N' 0x4e */
Packit cdaae3
1, /* 'O' 0x4f */
Packit cdaae3
1, /* 'P' 0x50 */
Packit cdaae3
1, /* 'Q' 0x51 */
Packit cdaae3
1, /* 'R' 0x52 */
Packit cdaae3
1, /* 'S' 0x53 */
Packit cdaae3
1, /* 'T' 0x54 */
Packit cdaae3
1, /* 'U' 0x55 */
Packit cdaae3
1, /* 'V' 0x56 */
Packit cdaae3
1, /* 'W' 0x57 */
Packit cdaae3
1, /* 'X' 0x58 */
Packit cdaae3
1, /* 'Y' 0x59 */
Packit cdaae3
1, /* 'Z' 0x5a */
Packit cdaae3
1, /* '[' 0x5b */
Packit cdaae3
1, /* '\' 0x5c */
Packit cdaae3
1, /* ']' 0x5d */
Packit cdaae3
1, /* '^' 0x5e */
Packit cdaae3
1, /* '_' 0x5f */
Packit cdaae3
0, /* '`' 0x60 */
Packit cdaae3
1, /* 'a' 0x61 */
Packit cdaae3
1, /* 'b' 0x62 */
Packit cdaae3
1, /* 'c' 0x63 */
Packit cdaae3
1, /* 'd' 0x64 */
Packit cdaae3
1, /* 'e' 0x65 */
Packit cdaae3
1, /* 'f' 0x66 */
Packit cdaae3
1, /* 'g' 0x67 */
Packit cdaae3
1, /* 'h' 0x68 */
Packit cdaae3
1, /* 'i' 0x69 */
Packit cdaae3
1, /* 'j' 0x6a */
Packit cdaae3
1, /* 'k' 0x6b */
Packit cdaae3
1, /* 'l' 0x6c */
Packit cdaae3
1, /* 'm' 0x6d */
Packit cdaae3
1, /* 'n' 0x6e */
Packit cdaae3
1, /* 'o' 0x6f */
Packit cdaae3
1, /* 'p' 0x70 */
Packit cdaae3
1, /* 'q' 0x71 */
Packit cdaae3
1, /* 'r' 0x72 */
Packit cdaae3
1, /* 's' 0x73 */
Packit cdaae3
1, /* 't' 0x74 */
Packit cdaae3
1, /* 'u' 0x75 */
Packit cdaae3
1, /* 'v' 0x76 */
Packit cdaae3
1, /* 'w' 0x77 */
Packit cdaae3
1, /* 'x' 0x78 */
Packit cdaae3
1, /* 'y' 0x79 */
Packit cdaae3
1, /* 'z' 0x7a */
Packit cdaae3
1, /* '{' 0x7b */
Packit cdaae3
1, /* '|' 0x7c */
Packit cdaae3
1, /* '}' 0x7d */
Packit cdaae3
1, /* '~' 0x7e */
Packit cdaae3
0, /* DEL 0x7f */
Packit cdaae3
1, /* 0x80 */
Packit cdaae3
1, /* 0x81 */
Packit cdaae3
1, /* 0x82 */
Packit cdaae3
1, /* 0x83 */
Packit cdaae3
1, /* 0x84 */
Packit cdaae3
1, /* 0x85 */
Packit cdaae3
1, /* 0x86 */
Packit cdaae3
1, /* 0x87 */
Packit cdaae3
1, /* 0x88 */
Packit cdaae3
1, /* 0x89 */
Packit cdaae3
1, /* 0x8a */
Packit cdaae3
1, /* 0x8b */
Packit cdaae3
1, /* 0x8c */
Packit cdaae3
1, /* 0x8d */
Packit cdaae3
1, /* 0x8e */
Packit cdaae3
1, /* 0x8f */
Packit cdaae3
1, /* 0x90 */
Packit cdaae3
1, /* 0x91 */
Packit cdaae3
1, /* 0x92 */
Packit cdaae3
1, /* 0x93 */
Packit cdaae3
1, /* 0x94 */
Packit cdaae3
1, /* 0x95 */
Packit cdaae3
1, /* 0x96 */
Packit cdaae3
1, /* 0x97 */
Packit cdaae3
1, /* 0x98 */
Packit cdaae3
1, /* 0x99 */
Packit cdaae3
1, /* 0x9a */
Packit cdaae3
1, /* 0x9b */
Packit cdaae3
1, /* 0x9c */
Packit cdaae3
1, /* 0x9d */
Packit cdaae3
1, /* 0x9e */
Packit cdaae3
1, /* 0x9f */
Packit cdaae3
0, /* other: 0xa0 */
Packit cdaae3
1, /* 0xa1 */
Packit cdaae3
1, /* 0xa2 */
Packit cdaae3
1, /* 0xa3 */
Packit cdaae3
1, /* 0xa4 */
Packit cdaae3
1, /* 0xa5 */
Packit cdaae3
1, /* 0xa6 */
Packit cdaae3
1, /* 0xa7 */
Packit cdaae3
1, /* 0xa8 */
Packit cdaae3
1, /* 0xa9 */
Packit cdaae3
1, /* 0xaa */
Packit cdaae3
1, /* 0xab */
Packit cdaae3
1, /* 0xac */
Packit cdaae3
1, /* 0xad */
Packit cdaae3
1, /* 0xae */
Packit cdaae3
1, /* 0xaf */
Packit cdaae3
1, /* 0xb0 */
Packit cdaae3
1, /* 0xb1 */
Packit cdaae3
1, /* 0xb2 */
Packit cdaae3
1, /* 0xb3 */
Packit cdaae3
1, /* 0xb4 */
Packit cdaae3
1, /* 0xb5 */
Packit cdaae3
1, /* 0xb6 */
Packit cdaae3
1, /* 0xb7 */
Packit cdaae3
1, /* 0xb8 */
Packit cdaae3
1, /* 0xb9 */
Packit cdaae3
1, /* 0xba */
Packit cdaae3
1, /* 0xbb */
Packit cdaae3
1, /* 0xbc */
Packit cdaae3
1, /* 0xbd */
Packit cdaae3
1, /* 0xbe */
Packit cdaae3
1, /* 0xbf */
Packit cdaae3
1, /* 0xc0 */
Packit cdaae3
1, /* 0xc1 */
Packit cdaae3
1, /* 0xc2 */
Packit cdaae3
1, /* 0xc3 */
Packit cdaae3
1, /* 0xc4 */
Packit cdaae3
1, /* 0xc5 */
Packit cdaae3
1, /* 0xc6 */
Packit cdaae3
1, /* 0xc7 */
Packit cdaae3
1, /* 0xc8 */
Packit cdaae3
1, /* 0xc9 */
Packit cdaae3
1, /* 0xca */
Packit cdaae3
1, /* 0xcb */
Packit cdaae3
1, /* 0xcc */
Packit cdaae3
1, /* 0xcd */
Packit cdaae3
1, /* 0xce */
Packit cdaae3
1, /* 0xcf */
Packit cdaae3
1, /* 0xd0 */
Packit cdaae3
1, /* 0xd1 */
Packit cdaae3
1, /* 0xd2 */
Packit cdaae3
1, /* 0xd3 */
Packit cdaae3
1, /* 0xd4 */
Packit cdaae3
1, /* 0xd5 */
Packit cdaae3
1, /* 0xd6 */
Packit cdaae3
1, /* 0xd7 */
Packit cdaae3
1, /* 0xd8 */
Packit cdaae3
1, /* 0xd9 */
Packit cdaae3
1, /* 0xda */
Packit cdaae3
1, /* 0xdb */
Packit cdaae3
1, /* 0xdc */
Packit cdaae3
1, /* 0xdd */
Packit cdaae3
1, /* 0xde */
Packit cdaae3
1, /* 0xdf */
Packit cdaae3
1, /* 0xe0 */
Packit cdaae3
1, /* 0xe1 */
Packit cdaae3
1, /* 0xe2 */
Packit cdaae3
1, /* 0xe3 */
Packit cdaae3
1, /* 0xe4 */
Packit cdaae3
1, /* 0xe5 */
Packit cdaae3
1, /* 0xe6 */
Packit cdaae3
1, /* 0xe7 */
Packit cdaae3
1, /* 0xe8 */
Packit cdaae3
1, /* 0xe9 */
Packit cdaae3
1, /* 0xea */
Packit cdaae3
1, /* 0xeb */
Packit cdaae3
1, /* 0xec */
Packit cdaae3
1, /* 0xed */
Packit cdaae3
1, /* 0xee */
Packit cdaae3
1, /* 0xef */
Packit cdaae3
1, /* 0xf0 */
Packit cdaae3
1, /* 0xf1 */
Packit cdaae3
1, /* 0xf2 */
Packit cdaae3
1, /* 0xf3 */
Packit cdaae3
1, /* 0xf4 */
Packit cdaae3
1, /* 0xf5 */
Packit cdaae3
1, /* 0xf6 */
Packit cdaae3
1, /* 0xf7 */
Packit cdaae3
1, /* 0xf8 */
Packit cdaae3
1, /* 0xf9 */
Packit cdaae3
1, /* 0xfa */
Packit cdaae3
1, /* 0xfb */
Packit cdaae3
1, /* 0xfc */
Packit cdaae3
1, /* 0xfd */
Packit cdaae3
1, /* 0xfe */
Packit cdaae3
0, /* other: 0xff */
Packit cdaae3
};
Packit cdaae3
static char *
Packit cdaae3
xchar(int c, char *buf, int size)
Packit cdaae3
{
Packit cdaae3
    snprintf(buf, size,"%%%02x",c);
Packit cdaae3
    return buf;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
/* Translate dangerous and some other characters to safe
Packit cdaae3
   %xx form.
Packit cdaae3
*/
Packit cdaae3
void
Packit cdaae3
translate_to_uri(const char * filename, struct esb_s *out)
Packit cdaae3
{
Packit cdaae3
    char buf[8];
Packit cdaae3
    const char *cp = 0;
Packit cdaae3
    for (cp = filename  ; *cp; ++cp) {
Packit cdaae3
        char v[2];
Packit cdaae3
        int c = 0xff & (unsigned char)*cp;
Packit cdaae3
        if (dwarfdump_ctype_table[c]) {
Packit cdaae3
            v[0] = c;
Packit cdaae3
            v[1] = 0;
Packit cdaae3
            esb_append(out,v);
Packit cdaae3
        } else {
Packit cdaae3
            char *b = xchar(c,buf,sizeof(buf));
Packit cdaae3
            esb_append(out,b);
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
/* This is not very efficient, but it is seldom called. */
Packit cdaae3
static char
Packit cdaae3
hexdig(char c)
Packit cdaae3
{
Packit cdaae3
    char ochar = 0;
Packit cdaae3
    if (c >= '0' && c <= '9') {
Packit cdaae3
        ochar = (c - '0');
Packit cdaae3
        return ochar;
Packit cdaae3
    }
Packit cdaae3
    if (c >= 'a' && c <= 'f') {
Packit cdaae3
        ochar = (c - 'a')+10;
Packit cdaae3
        return ochar;
Packit cdaae3
    }
Packit cdaae3
    if (c >= 'A' && c <= 'F') {
Packit cdaae3
        ochar = (c - 'A')+10;
Packit cdaae3
        return ochar;
Packit cdaae3
    }
Packit cdaae3
    /* We have an input botch here. */
Packit cdaae3
    fprintf(stderr,"Translating from uri: "
Packit cdaae3
        "A supposed hexadecimal input character is "
Packit cdaae3
        "not 0-9 or a-f or A-F, it is (shown as hex here): %x\n",c);
Packit cdaae3
    return ochar;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
static char tohex(char c1, char c2)
Packit cdaae3
{
Packit cdaae3
    char out = (hexdig(c1) << 4) | hexdig(c2);
Packit cdaae3
    return out;
Packit cdaae3
}
Packit cdaae3
static int
Packit cdaae3
hexpairtochar(const char *cp, char*myochar)
Packit cdaae3
{
Packit cdaae3
    char ochar = 0;
Packit cdaae3
    int olen = 0;
Packit cdaae3
    char c = cp[0];
Packit cdaae3
    if (c) {
Packit cdaae3
        char c2 = cp[1];
Packit cdaae3
        if (c2) {
Packit cdaae3
            ochar = tohex(c,c2);
Packit cdaae3
            olen = 2;
Packit cdaae3
        } else {
Packit cdaae3
            fprintf(stderr,"Translating from uri: "
Packit cdaae3
                "A supposed hexadecimal input character pair "
Packit cdaae3
                "runs off the end of the input after 1 hex digit.\n");
Packit cdaae3
            /* botched input. */
Packit cdaae3
            ochar = c;
Packit cdaae3
            olen = 1;
Packit cdaae3
        }
Packit cdaae3
    } else {
Packit cdaae3
        /* botched input. */
Packit cdaae3
        fprintf(stderr,"Translating from uri: "
Packit cdaae3
            "A supposed hexadecimal input character pair "
Packit cdaae3
            "runs off the end of the input.\n");
Packit cdaae3
        ochar = '%';
Packit cdaae3
        olen = 0;
Packit cdaae3
    }
Packit cdaae3
    *myochar = ochar;
Packit cdaae3
    return olen;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
void
Packit cdaae3
translate_from_uri(const char * input, struct esb_s* out)
Packit cdaae3
{
Packit cdaae3
    const char *cp = input;
Packit cdaae3
    char tempstr[2];
Packit cdaae3
    for (; *cp; ++cp) {
Packit cdaae3
        char c = *cp;
Packit cdaae3
        if (c == '%') {
Packit cdaae3
            int increment = 0;
Packit cdaae3
            char c2 = cp[1];
Packit cdaae3
            /* hexpairtochar deals with c2 being NUL. */
Packit cdaae3
            if (c2  == '%') {
Packit cdaae3
                tempstr[0] = c;
Packit cdaae3
                tempstr[1] = 0;
Packit cdaae3
                esb_append(out,tempstr);
Packit cdaae3
                ++cp;
Packit cdaae3
                continue;
Packit cdaae3
            }
Packit cdaae3
Packit cdaae3
            increment = hexpairtochar(cp+1,&c);
Packit cdaae3
            tempstr[0] = c;
Packit cdaae3
            tempstr[1] = 0;
Packit cdaae3
            esb_append(out,tempstr);
Packit cdaae3
            cp +=increment;
Packit cdaae3
            continue;
Packit cdaae3
        }
Packit cdaae3
        tempstr[0] = c;
Packit cdaae3
        tempstr[1] = 0;
Packit cdaae3
        esb_append(out,tempstr);
Packit cdaae3
    }
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
Packit cdaae3
Packit cdaae3
#ifdef TEST
Packit cdaae3
Packit cdaae3
unsigned errcnt = 0;
Packit cdaae3
Packit cdaae3
static void
Packit cdaae3
mytestfrom(const char * in,const char *expected,int testnum)
Packit cdaae3
{
Packit cdaae3
    struct esb_s out;
Packit cdaae3
    esb_constructor(&out;;
Packit cdaae3
    translate_from_uri(in, &out;;
Packit cdaae3
    if (strcmp(expected, esb_get_string(&out))) {
Packit cdaae3
        printf(" Fail test %d expected \"%s\" got \"%s\"\n",
Packit cdaae3
            testnum,expected,esb_get_string(&out));
Packit cdaae3
        ++errcnt;
Packit cdaae3
    }
Packit cdaae3
    esb_destructor(&out;;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
static void
Packit cdaae3
mytest(char *in,char *expected,int testnum)
Packit cdaae3
{
Packit cdaae3
    struct esb_s out;
Packit cdaae3
    esb_constructor(&out;;
Packit cdaae3
    translate_to_uri(in, &out;;
Packit cdaae3
    if (strcmp(expected, esb_get_string(&out))) {
Packit cdaae3
        printf(" Fail test %d expected %s got %s\n",testnum,expected,esb_get_string(&out));
Packit cdaae3
        ++errcnt;
Packit cdaae3
    }
Packit cdaae3
    esb_destructor(&out;;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
int
Packit cdaae3
main()
Packit cdaae3
{
Packit cdaae3
    /* We no longer translate space to %20, that
Packit cdaae3
    turns out not to help all that much. */
Packit cdaae3
    mytest("aaa","aaa",1);
Packit cdaae3
    mytest(" bc"," bc",2);
Packit cdaae3
    mytest(";bc","%3bbc",3);
Packit cdaae3
    mytest(" bc\n"," bc%0a",4);
Packit cdaae3
    mytest(";bc\n","%3bbc%0a",5);
Packit cdaae3
    mytest(" bc\r"," bc%0d",6);
Packit cdaae3
    mytest(";bc\r","%3bbc%0d",7);
Packit cdaae3
    mytest(" \x01"," %01",8);
Packit cdaae3
    mytest(";\x01","%3b%01",9);
Packit cdaae3
    mytestfrom("abc","abc",10);
Packit cdaae3
    mytestfrom("a%20bc","a bc",11);
Packit cdaae3
    mytestfrom("a%%20bc","a%20bc",12);
Packit cdaae3
    mytestfrom("a%%%20bc","a% bc",13);
Packit cdaae3
    mytestfrom("a%%%%20bc","a%%20bc",14);
Packit cdaae3
    mytestfrom("a%20","a ",15);
Packit cdaae3
    /* The following is mistaken input. */
Packit cdaae3
    mytestfrom("a%2","a2",16);
Packit cdaae3
    mytestfrom("a%","a%",17);
Packit cdaae3
    mytest("%bc","%25bc",18);
Packit cdaae3
Packit cdaae3
    if (errcnt) {
Packit cdaae3
        printf("uri errcount ",errcnt);
Packit cdaae3
    }
Packit cdaae3
    return errcnt? 1:0;
Packit cdaae3
}
Packit cdaae3
#endif
Packit cdaae3