[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FDclone-users:00315] Re: cannot enter ./ in an archive
- Subject: [FDclone-users:00315] Re: cannot enter ./ in an archive
- From: Takashi SHIRAI <shirai@unixusers.net>
- Date: Sat, 17 Jul 2004 05:14:51 +0900
しらいです。
In Message-Id <86ekncgmdi.knu@iDaemons.org>
"Akinori MUSHA" <knu@iDaemons.org>さんwrites:
> > のように正規化するルールにしてみました。
>
> 正規化してしまうと、ファイルの閲覧や抽出などができません。
> 厄介なことですが、 tar(1) はパス名の正規化ということはしない
> ので、「./foo」として格納されているファイルを「foo」と言っても
> それとは認識してくれません。
なるほど。だとすると、正規化して同じ pathname になるような
entry を archive の中から探して、展開時の指定 filename をす
げ替えてやる必要がありますね。
でも、全く同じ pathname に正規化されてしまう複数 entry が
存在すると厄介ですね。そもそも元の archive 構成が見えなくな
るのも一長一短だし。
余り複雑で奇妙な構成の archive にばかり気を取られるのはや
めておきましょうか。取り敢えず、何らかの形で「..」を含むよう
な entry も扱えるようになれば良しとしましょう。
という訳で仕切り直しです。
---- Cut Here ----
diff -u ../old/FD-2.05g/archive.c ./archive.c
--- ../old/FD-2.05g/archive.c Wed Jul 7 00:00:00 2004
+++ ./archive.c Sat Jul 17 04:59:55 2004
@@ -188,6 +188,7 @@
static VOID NEAR unpackerror __P_((VOID_A));
static int NEAR readarchive __P_((char *, launchtable *, int));
static char *NEAR searcharcdir __P_((char *, int));
+static char *NEAR archoutdir __P_((VOID_A));
static int NEAR undertmp __P_((char *));
#ifdef _NODOSDRIVE
static char *NEAR genfullpath __P_((char *, char *, char *));
@@ -457,9 +458,7 @@
int i, c, len;
u_int mode;
- if (!*buf) return(0);
len = strlen(buf);
-
if (len < 9) {
mode = (tmp -> st_mode & S_IFMT) | S_IREAD_ALL | S_IWRITE_ALL;
while (--len >= 0) {
@@ -547,7 +546,7 @@
}
tmp -> st_mode = mode;
- return(1);
+ return(len);
}
#if FD >= 2
@@ -836,21 +835,24 @@
err = 0;
break;
default:
- free(buf);
- free(rawbuf);
- if (tmp -> name) free(tmp -> name);
+ hit = -1;
+ break;
+ }
+
+ free(buf);
+ free(rawbuf);
+
+ if (hit < 0) {
+ if (tmp -> name) free(tmp -> name);
# ifndef NOSYMLINK
- if (tmp -> linkname) free(tmp -> linkname);
+ if (tmp -> linkname) free(tmp -> linkname);
# endif
- return(-1);
-/*NOTREACHED*/
- break;
+ return(hit);
}
+
if (!hit) score += 5;
else if (hit <= err2) score += err2;
score += err;
- free(buf);
- free(rawbuf);
line += len;
if (!ch) while (iswhitespace(*line)) line++;
}
@@ -1024,7 +1026,7 @@
tmp -> name = strdup2(buf);
getfield(buf, line, skip, list, F_MODE);
- if (!readattr(tmp, buf)) tmp -> st_mode = 0644;
+ readattr(tmp, buf);
if (!(tmp -> st_mode & S_IFMT)) tmp -> st_mode |= S_IFREG;
if (s_isdir(tmp)) tmp -> flags |= F_ISDIR;
else if (s_islnk(tmp)) tmp -> flags |= F_ISLNK;
@@ -1241,15 +1243,14 @@
static char *NEAR pseudodir(namep)
namelist *namep;
{
- char *cp, *tmp;
+ char *cp, *next;
int i, len;
u_short ent;
- cp = namep -> name;
- while ((tmp = strdelim(cp, 0))) {
- while (*(tmp + 1) == _SC_) tmp++;
- if (!*(tmp + 1)) break;
- len = tmp - (namep -> name);
+ for (cp = namep -> name; (next = strdelim(cp, 0)); cp = next + 1) {
+ while (*(next + 1) == _SC_) next++;
+ if (!*(next + 1)) break;
+ len = next - namep -> name;
if (!len) len++;
for (i = 0; i < maxfile; i++) {
if (isdir(&(filelist[i]))
@@ -1261,21 +1262,22 @@
filelist[i].name = realloc2(filelist[i].name, len + 1);
strncpy2(filelist[i].name, namep -> name, len);
}
- cp = tmp + 1;
}
+
if (isdir(namep) && !isdotdir(namep -> name))
for (i = 0; i < maxfile; i++) {
if (isdir(&(filelist[i]))
&& !dircmp(filelist[i].name, namep -> name)) {
- tmp = filelist[i].name;
+ cp = filelist[i].name;
ent = filelist[i].ent;
memcpy((char *)&(filelist[i]), (char *)namep,
sizeof(namelist));
- filelist[i].name = tmp;
+ filelist[i].name = cp;
filelist[i].ent = ent;
return(NULL);
}
}
+
return(namep -> name);
}
@@ -1609,7 +1611,7 @@
#ifndef NOSYMLINK
filelist[0].linkname = NULL;
#endif
- filelist[0].flags = F_ISDIR;
+ filelist[0].flags = (F_ISDIR | F_ISRED | F_ISWRI);
filelist[0].tmpflags = F_STAT;
maxfile++;
#ifdef HAVEFLAGS
@@ -1713,25 +1715,26 @@
char *arcre;
{
char *cp, *tmp;
- int i, j, n, len;
+ int i, j, n, len, parent;
+ parent = (*archivedir) ? 0 : -1;
+ /* omit filelist[0] as pseudo ".." */
for (i = 1; i < maxarcf; i++) {
if (!*archivedir) len = 0;
else if (!(len = dirmatchlen(archivedir, arcflist[i].name)))
continue;
- cp = arcflist[i].name + len;
- if (len > 0 && (len > 1 || *archivedir != _SC_)) cp++;
- if (!arcflist[i].name[len]) {
- memcpy((char *)&(filelist[0]),
- (char *)&(arcflist[i]), sizeof(namelist));
- filelist[0].name = arcflist[0].name;
-#ifndef NOSYMLINK
- filelist[0].linkname = NULL;
-#endif
+ cp = &(arcflist[i].name[len]);
+ if (*cp && len > 0 && (len > 1 || *archivedir != _SC_)) cp++;
+ if (!*cp) {
+ parent = i;
continue;
}
- if ((tmp = strdelim(cp, 0))) while (*(++tmp) == _SC_);
+ if ((tmp = strdelim(cp, 0))) {
+ if (tmp - cp == 2 && cp[0] == '.' && cp[1] == '.')
+ if (parent <= 0) parent = i;
+ while (*(++tmp) == _SC_);
+ }
if ((tmp && *tmp) || (re && !regexp_exec(re, cp, 1))) continue;
if (arcre) {
if (!(n = searcharc(arcre, arcflist, maxarcf, i)))
@@ -1751,6 +1754,18 @@
#endif
maxfile++;
}
+
+ if (parent < 0) return;
+ for (i = 0; i < maxfile; i++)
+ if (!strcmp(filelist[i].name, "..")) return;
+ memmove((char *)&(filelist[1]), (char *)&(filelist[0]),
+ maxfile++ * sizeof(namelist));
+ memcpy((char *)&(filelist[0]),
+ (char *)&(arcflist[parent]), sizeof(namelist));
+ filelist[0].name = arcflist[0].name;
+#ifndef NOSYMLINK
+ filelist[0].linkname = NULL;
+#endif
}
static char *NEAR searcharcdir(file, flen)
@@ -1761,14 +1776,14 @@
int i, len;
errno = ENOENT;
- for (i = 1; i < maxarcf; i++) {
+ for (i = 0; i < maxarcf; i++) {
if (!*archivedir) len = 0;
else if (!(len = dirmatchlen(archivedir, arcflist[i].name)))
continue;
- cp = arcflist[i].name + len;
- if (len > 0 && (len > 1 || *archivedir != _SC_)) cp++;
- if (!arcflist[i].name[len]) {
+ cp = &(arcflist[i].name[len]);
+ if (*cp && len > 0 && (len > 1 || *archivedir != _SC_)) cp++;
+ if (!*cp) {
if (file) continue;
}
else {
@@ -1778,6 +1793,8 @@
len = (tmp == cp) ? 1 : tmp - cp;
while (*(++tmp) == _SC_);
}
+ if (!*file && len == 2 && cp[0] == '.' && cp[1] == '.')
+ return(arcflist[0].name);
if ((tmp && *tmp) || len != flen
|| strnpathcmp(file, cp, flen))
continue;
@@ -1791,6 +1808,29 @@
return(NULL);
}
+static char *NEAR archoutdir(VOID_A)
+{
+ char *cp, *file;
+
+ if (!*archivedir) return((char *)-1);
+ if (!(file = searcharcdir(NULL, 0))) return(NULL);
+
+ cp = file + (int)strlen(file) - 1;
+ while (cp > file && *cp == _SC_) cp--;
+#ifdef BSPATHDELIM
+ if (onkanji1(file, cp - file)) cp++;
+#endif
+ cp = strrdelim2(file, cp);
+ if (!cp) *archivedir = '\0';
+ else {
+ if (cp == file) strcpy(archivedir, _SS_);
+ else strncpy2(archivedir, file, cp - file);
+ file = cp + 1;
+ }
+
+ return(file);
+}
+
char *archchdir(path)
char *path;
{
@@ -1799,11 +1839,11 @@
if (findpattern) free(findpattern);
findpattern = NULL;
- if (!path || !*path) path = "..";
#ifndef _NOBROWSE
if (browselist) {
int i, n, dupfilepos;
+ if (!path || !*path) path = "..";
if ((cp = strdelim(path, 0))) {
for (i = 1; cp[i]; i++) if (cp[i] != _SC_) break;
if (cp[i]) {
@@ -1846,43 +1886,28 @@
return("..");
}
#endif /* !_NOBROWSE */
+
+ if (!path) return(archoutdir());
strcpy(duparcdir, archivedir);
do {
if (*path == _SC_) len = 1;
else if ((cp = strdelim(path, 0))) len = cp - path;
else len = strlen(path);
- if (len == 1 && *path == '.') file = "..";
- else if (len != 2 || strncmp(path, "..", len)) {
- if (!searcharcdir(path, len)) {
- strcpy(archivedir, duparcdir);
- errno = ENOENT;
- return(NULL);
- }
+ cp = path;
+ if (len == 2 && path[0] == '.' && path[1] == '.') cp = "";
+ if (searcharcdir(cp, len)) {
if (*(cp = archivedir)) cp = strcatdelim(archivedir);
strncpy2(cp, path, len);
file = "..";
}
- else if (!*archivedir) return((char *)-1);
- else {
- if (!(file = searcharcdir(NULL, 0))) {
- strcpy(archivedir, duparcdir);
- errno = ENOENT;
- return(NULL);
- }
- cp = file + (int)strlen(file) - 1;
- while (cp > file && *cp == _SC_) cp--;
-#ifdef BSPATHDELIM
- if (onkanji1(file, cp - file)) cp++;
-#endif
- cp = strrdelim2(file, cp);
- if (!cp) *archivedir = '\0';
- else {
- if (cp == file) strcpy(archivedir, _SS_);
- else strncpy2(archivedir, file, cp - file);
- file = cp + 1;
- }
+ else if (*cp || !(file = archoutdir())) {
+ strcpy(archivedir, duparcdir);
+ errno = ENOENT;
+ return(NULL);
}
+ else if (file == (char *)-1) break;
+
path += len;
while (*path == _SC_) path++;
} while (*path);
@@ -1897,7 +1922,7 @@
char ***argvp;
{
char *cp, *tmp, *new, *file, dir[MAXPATHLEN], duparcdir[MAXPATHLEN];
- int i, len;
+ int i, len, parent;
# ifdef _USEDOSPATH
if (_dospath(path)) return(argc);
@@ -1917,25 +1942,35 @@
flen -= ++file - path;
}
+ /* omit filelist[0] as pseudo ".." */
for (i = 1; i < maxarcf; i++) {
if (!*archivedir) len = 0;
else if (!(len = dirmatchlen(archivedir, arcflist[i].name)))
continue;
- cp = arcflist[i].name + len;
- if (len > 0 && (len > 1 || *archivedir != _SC_)) cp++;
- if (!arcflist[i].name[len]) continue;
+ cp = &(arcflist[i].name[len]);
+ if (*cp && len > 0 && (len > 1 || *archivedir != _SC_)) cp++;
+ if (!*cp) continue;
if (!(tmp = strdelim(cp, 0))) len = strlen(cp);
else {
len = (tmp == cp) ? 1 : tmp - cp;
while (*(++tmp) == _SC_);
}
- if ((tmp && *tmp) || strnpathcmp(file, cp, flen)) continue;
+
+ parent = 0;
+ if (len == 2 && cp[0] == '.' && cp[1] == '.') {
+ if (strnpathcmp(file, cp, flen)) continue;
+ parent++;
+ }
+ else {
+ if ((tmp && *tmp) || strnpathcmp(file, cp, flen))
+ continue;
+ }
new = malloc2(len + 1 + 1);
strncpy(new, cp, len);
- if (isdir(&(arcflist[i]))) new[len++] = _SC_;
+ if (parent || isdir(&(arcflist[i]))) new[len++] = _SC_;
new[len] = '\0';
if (finddupl(new, argc, *argvp)) {
free(new);
diff -u ../old/FD-2.05g/browse.c ./browse.c
--- ../old/FD-2.05g/browse.c Wed Jul 7 00:00:00 2004
+++ ./browse.c Sat Jul 17 02:56:26 2004
@@ -707,7 +707,7 @@
struct tm *tm;
int len;
- if (!filelist || maxfile < 0) return;
+ if (!filelist || filepos < 0 || maxfile < 0) return;
#ifndef _NOTRADLAYOUT
if (istradlayout()) {
@@ -1216,7 +1216,7 @@
VOID rewritefile(all)
int all;
{
- if (!filelist || maxfile < 0) return;
+ if (!filelist || filepos < 0 || maxfile < 0) return;
if (all > 0) {
title();
helpbar();
@@ -1439,9 +1439,9 @@
re = regexp_init(findpattern, -1);
}
+ maxfile = 0;
#ifndef _NOARCHIVE
if (archivefile) {
- maxfile = (*archivedir) ? 1 : 0;
blocksize = (off_t)1;
if (sorttype < 100) sorton = 0;
copyarcf(re, arcre);
@@ -1449,7 +1449,6 @@
else
#endif
{
- maxfile = 0;
blocksize = getblocksize(".");
if (sorttype < 100) sorton = sorttype;
if (readfilelist(re, arcre)) {
@@ -1657,8 +1656,9 @@
else if (no > 4) {
char *tmp;
- tmp = (filepos < 0) ? ".." : filelist[filepos].name;
+ tmp = (filepos >= 0) ? filelist[filepos].name : NULL;
if (!(cp = archchdir(tmp))) {
+ if (!tmp) tmp = "..";
warning(-1, tmp);
strcpy(file, tmp);
}
---- Cut Here ----
しらい たかし