ATLAS Offline Software
urldecode.h
Go to the documentation of this file.
1 /* urldecode - decode application/x-www-form-urlencoded data
2 
3  Copyright (C) 2009 ePoint Systems Ltd.
4  Author: Rooslan S. Khayrov
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <unistd.h>
21 #include <strings.h>
22 #include <sstream>
23 #include <string>
24 
25 namespace urldecode
26 {
27 
28 static int hexdigit(char c)
29 {
30  if (c >= '0' && c <= '9')
31  return c - '0';
32  if (c >= 'A' && c <= 'F')
33  return 10 + c - 'A';
34  if (c >= 'a' && c <= 'f')
35  return 10 + c - 'a';
36  return -1;
37 }
38 
40 
41 typedef struct decoder_state_s
42 {
43  int state;
44  char sym;
46 
47 int is_unreserved(char c)
48 {
49  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
50  (c >= '0' && c <= '9') || index("-_.~!*'();:@&=+$,/?%#[]", c);
51 }
52 
59 ssize_t urldecode(decoder_state *state, char *data, size_t size)
60 {
61  size_t inpos = 0, outpos = 0;
62  int d1, d2;
63  while (inpos < size)
64  {
65  char in = data[inpos++];
66  switch (in)
67  {
68  case '%':
69  switch (state->state)
70  {
71  case ST_SYM:
72  state->state = ST_PERCENT;
73  break;
74  default:
75  return -1;
76  }
77  break;
78  case '+':
79  switch (state->state)
80  {
81  case ST_SYM:
82  data[outpos++] = ' ';
83  break;
84  default:
85  return -1;
86  }
87  break;
88  default:
89  switch (state->state)
90  {
91  case ST_PERCENT_AND_SYM:
92  d1 = hexdigit(state->sym), d2 = hexdigit(in);
93  if (d1 >= 0 && d2 >= 0)
94  {
95  data[outpos++] = (d1 << 4) | d2;
96  }
97  else
98  {
99  return -1;
100  }
101  state->state = ST_SYM;
102  break;
103  case ST_PERCENT:
104  state->sym = in;
105  state->state = ST_PERCENT_AND_SYM;
106  break;
107  case ST_SYM:
108  if (is_unreserved(in))
109  {
110  data[outpos++] = in;
111  }
112  else
113  {
114  return -1;
115  }
116  break;
117  }
118  }
119  }
120  return outpos;
121 }
122 
123 
124 std::pair<std::string,int> urldecode(decoder_state *state, const std::string& data, size_t size)
125 {
126  size_t inpos = 0;
127  int outpos = 0;
128  int d1, d2;
129  std::stringstream output;
130  while (inpos < size)
131  {
132  char in = data[inpos++];
133  switch (in)
134  {
135  case '%':
136  switch (state->state)
137  {
138  case ST_SYM:
139  state->state = ST_PERCENT;
140  break;
141  default:
142  outpos=-1;
143  }
144  break;
145  case '+':
146  switch (state->state)
147  {
148  case ST_SYM:
149  //data[outpos++] = ' ';
150  output << ' ';
151  break;
152  default:
153  outpos=-1;
154  }
155  break;
156  default:
157  switch (state->state)
158  {
159  case ST_PERCENT_AND_SYM:
160  d1 = hexdigit(state->sym), d2 = hexdigit(in);
161  if (d1 >= 0 && d2 >= 0)
162  {
163  //data[outpos++] = (d1 << 4) | d2;
164  char temp = (d1 << 4) | d2;
165  output << temp;
166  }
167  else
168  {
169  outpos=-1;
170  }
171  state->state = ST_SYM;
172  break;
173  case ST_PERCENT:
174  state->sym = in;
175  state->state = ST_PERCENT_AND_SYM;
176  break;
177  case ST_SYM:
178  if (is_unreserved(in))
179  {
180  //data[outpos++] = in;
181  output << in;
182  }
183  else
184  {
185  outpos=-1;
186  }
187  break;
188  }
189  }
190  }
191  return std::make_pair(output.str(),outpos);
192 }
193 
194 } // end namespace urldecode
urldecode::decoder_state_s::state
int state
Definition: urldecode.h:43
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
urldecode::decoder_state_s::sym
char sym
Definition: urldecode.h:44
urldecode::decoder_state_s
Definition: urldecode.h:42
dq_defect_virtual_defect_validation.d1
d1
Definition: dq_defect_virtual_defect_validation.py:79
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
urldecode::decoder_state
struct urldecode::decoder_state_s decoder_state
urldecode::states
states
Definition: urldecode.h:39
urldecode::ST_PERCENT_AND_SYM
@ ST_PERCENT_AND_SYM
Definition: urldecode.h:39
merge.output
output
Definition: merge.py:17
urldecode
Definition: urldecode.h:26
urldecode::ST_SYM
@ ST_SYM
Definition: urldecode.h:39
DeMoScan.index
string index
Definition: DeMoScan.py:362
urldecode::is_unreserved
int is_unreserved(char c)
Definition: urldecode.h:47
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
urldecode::ST_PERCENT
@ ST_PERCENT
Definition: urldecode.h:39
python.compressB64.c
def c
Definition: compressB64.py:93
urldecode::urldecode
ssize_t urldecode(decoder_state *state, char *data, size_t size)
Decodes URL-encoded data.
Definition: urldecode.h:59