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