Line 0
Link Here
|
|
|
1 |
/* |
2 |
* Path sanitation code by Ludwig Nussel <ludwig.nussel@suse.de>. Public Domain. |
3 |
*/ |
4 |
|
5 |
#include "unarj.h" |
6 |
|
7 |
#include <string.h> |
8 |
#include <limits.h> |
9 |
#include <stdio.h> |
10 |
|
11 |
#ifndef PATH_CHAR |
12 |
#define PATH_CHAR '/' |
13 |
#endif |
14 |
#ifndef MIN |
15 |
#define MIN(x,y) ((x)<(y)?(x):(y)) |
16 |
#endif |
17 |
|
18 |
/* copy src into dest converting the path to a relative one inside the current |
19 |
* directory. dest must hold at least len bytes */ |
20 |
void copy_path_relative(char *dest, char *src, size_t len) |
21 |
{ |
22 |
char* o = dest; |
23 |
char* p = src; |
24 |
|
25 |
*o = '\0'; |
26 |
|
27 |
while(*p && *p == PATH_CHAR) ++p; |
28 |
for(; len && *p;) |
29 |
{ |
30 |
src = p; |
31 |
p = strchr(src, PATH_CHAR); |
32 |
if(!p) p = src+strlen(src); |
33 |
|
34 |
/* . => skip */ |
35 |
if(p-src == 1 && *src == '.' ) |
36 |
{ |
37 |
if(*p) src = ++p; |
38 |
} |
39 |
/* .. => pop one */ |
40 |
else if(p-src == 2 && *src == '.' && src[1] == '.') |
41 |
{ |
42 |
if(o != dest) |
43 |
{ |
44 |
char* tmp; |
45 |
*o = '\0'; |
46 |
tmp = strrchr(dest, PATH_CHAR); |
47 |
if(!tmp) |
48 |
{ |
49 |
len += o-dest; |
50 |
o = dest; |
51 |
if(*p) ++p; |
52 |
} |
53 |
else |
54 |
{ |
55 |
len += o-tmp; |
56 |
o = tmp; |
57 |
if(*p) ++p; |
58 |
} |
59 |
} |
60 |
else /* nothing to pop */ |
61 |
if(*p) ++p; |
62 |
} |
63 |
else |
64 |
{ |
65 |
size_t copy; |
66 |
if(o != dest) |
67 |
{ |
68 |
--len; |
69 |
*o++ = PATH_CHAR; |
70 |
} |
71 |
copy = MIN(p-src,len); |
72 |
memcpy(o, src, copy); |
73 |
len -= copy; |
74 |
src += copy; |
75 |
o += copy; |
76 |
if(*p) ++p; |
77 |
} |
78 |
while(*p && *p == PATH_CHAR) ++p; |
79 |
} |
80 |
o[len?0:-1] = '\0'; |
81 |
} |