opt
cpr
opt
curl
lib
dotdot.c
Go to the documentation of this file.
1
/***************************************************************************
2
* _ _ ____ _
3
* Project ___| | | | _ \| |
4
* / __| | | | |_) | |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
7
*
8
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9
*
10
* This software is licensed as described in the file COPYING, which
11
* you should have received as part of this distribution. The terms
12
* are also available at https://curl.haxx.se/docs/copyright.html.
13
*
14
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
* copies of the Software, and permit persons to whom the Software is
16
* furnished to do so, under the terms of the COPYING file.
17
*
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
20
*
21
***************************************************************************/
22
23
#include "
curl_setup.h
"
24
25
#include <
curl/curl.h
>
26
27
#include "
dotdot.h
"
28
#include "
curl_memory.h
"
29
30
/* The last #include file should be: */
31
#include "
memdebug.h
"
32
33
/*
34
* "Remove Dot Segments"
35
* https://tools.ietf.org/html/rfc3986#section-5.2.4
36
*/
37
38
/*
39
* Curl_dedotdotify()
40
* @unittest: 1395
41
*
42
* This function gets a zero-terminated path with dot and dotdot sequences
43
* passed in and strips them off according to the rules in RFC 3986 section
44
* 5.2.4.
45
*
46
* The function handles a query part ('?' + stuff) appended but it expects
47
* that fragments ('#' + stuff) have already been cut off.
48
*
49
* RETURNS
50
*
51
* an allocated dedotdotified output string
52
*/
53
char
*
Curl_dedotdotify
(
const
char
*
input
)
54
{
55
size_t
inlen = strlen(
input
);
56
char
*clone;
57
size_t
clen = inlen;
/* the length of the cloned input */
58
char
*out =
malloc
(inlen + 1);
59
char
*outptr;
60
char
*orgclone;
61
char
*queryp;
62
if
(!out)
63
return
NULL;
/* out of memory */
64
65
/* get a cloned copy of the input */
66
clone =
strdup
(
input
);
67
if
(!clone) {
68
free
(out);
69
return
NULL;
70
}
71
orgclone = clone;
72
outptr = out;
73
74
if
(!*clone) {
75
/* zero length string, return that */
76
free
(out);
77
return
clone;
78
}
79
80
/*
81
* To handle query-parts properly, we must find it and remove it during the
82
* dotdot-operation and then append it again at the end to the output
83
* string.
84
*/
85
queryp = strchr(clone,
'?'
);
86
if
(queryp)
87
*queryp = 0;
88
89
do
{
90
91
/* A. If the input buffer begins with a prefix of "../" or "./", then
92
remove that prefix from the input buffer; otherwise, */
93
94
if
(!strncmp(
"./"
, clone, 2)) {
95
clone += 2;
96
clen -= 2;
97
}
98
else
if
(!strncmp(
"../"
, clone, 3)) {
99
clone += 3;
100
clen -= 3;
101
}
102
103
/* B. if the input buffer begins with a prefix of "/./" or "/.", where
104
"." is a complete path segment, then replace that prefix with "/" in
105
the input buffer; otherwise, */
106
else
if
(!strncmp(
"/./"
, clone, 3)) {
107
clone += 2;
108
clen -= 2;
109
}
110
else
if
(!strcmp(
"/."
, clone)) {
111
clone[1]=
'/'
;
112
clone++;
113
clen -= 1;
114
}
115
116
/* C. if the input buffer begins with a prefix of "/../" or "/..", where
117
".." is a complete path segment, then replace that prefix with "/" in
118
the input buffer and remove the last segment and its preceding "/" (if
119
any) from the output buffer; otherwise, */
120
121
else
if
(!strncmp(
"/../"
, clone, 4)) {
122
clone += 3;
123
clen -= 3;
124
/* remove the last segment from the output buffer */
125
while
(outptr > out) {
126
outptr--;
127
if
(*outptr ==
'/'
)
128
break
;
129
}
130
*outptr = 0;
/* zero-terminate where it stops */
131
}
132
else
if
(!strcmp(
"/.."
, clone)) {
133
clone[2]=
'/'
;
134
clone += 2;
135
clen -= 2;
136
/* remove the last segment from the output buffer */
137
while
(outptr > out) {
138
outptr--;
139
if
(*outptr ==
'/'
)
140
break
;
141
}
142
*outptr = 0;
/* zero-terminate where it stops */
143
}
144
145
/* D. if the input buffer consists only of "." or "..", then remove
146
that from the input buffer; otherwise, */
147
148
else
if
(!strcmp(
"."
, clone) || !strcmp(
".."
, clone)) {
149
*clone = 0;
150
*out = 0;
151
}
152
153
else
{
154
/* E. move the first path segment in the input buffer to the end of
155
the output buffer, including the initial "/" character (if any) and
156
any subsequent characters up to, but not including, the next "/"
157
character or the end of the input buffer. */
158
159
do
{
160
*outptr++ = *clone++;
161
clen--;
162
}
while
(*clone && (*clone !=
'/'
));
163
*outptr = 0;
164
}
165
166
}
while
(*clone);
167
168
if
(queryp) {
169
size_t
qlen;
170
/* There was a query part, append that to the output. The 'clone' string
171
may now have been altered so we copy from the original input string
172
from the correct index. */
173
size_t
oindex = queryp - orgclone;
174
qlen = strlen(&
input
[oindex]);
175
memcpy
(outptr, &
input
[oindex], qlen + 1);
/* include the end zero byte */
176
}
177
178
free
(orgclone);
179
return
out;
180
}
strdup
#define strdup(ptr)
Definition:
curl_memory.h:122
Curl_dedotdotify
char * Curl_dedotdotify(const char *input)
Definition:
dotdot.c:53
input
Definition:
http2-upload.c:169
memcpy
memcpy(filename, filename1, strlen(filename1))
memdebug.h
curl_memory.h
malloc
#define malloc(size)
Definition:
curl_memory.h:124
free
#define free(ptr)
Definition:
curl_memory.h:130
dotdot.h
curl_setup.h
curl.h
rc_tagdetect_client
Author(s): Monika Florek-Jasinska
, Raphael Schaller
autogenerated on Sun May 15 2022 02:24:58