return first;
}
+static int
+copy_path_element(char *dst, const char *src, int size)
+{
+ int i;
+
+ if (size < 1) return 0;
+
+ for (i = 0; i < size; i++) {
+ dst[i] = src[i];
+ if (dst[i] == '\0')
+ return i;
+ if (dst[i] == '/') {
+ dst[++i] = 0;
+ return i;
+ }
+ }
+
+ dst[--i] = 0;
+
+ return i;
+}
+
+/* remove leading "xxx/../" and "./" */
+static int
+remove_dots(char *newpath, char *path, size_t size)
+{
+ int len;
+ char *p = newpath;
+
+ path = remove_leading_dots(path);
+
+ while (*path) {
+ if (path[0] == '.' && path[1] == '/')
+ path += 2;
+ else {
+ int len;
+ len = copy_path_element(newpath, path, size);
+
+ path += len;
+ newpath += len;
+ size -= len;
+ if (size <= 1)
+ break;
+ }
+ }
+
+ /* When newpath is empty, set "." */
+ if (newpath == p) {
+ strcpy(newpath, ".");
+ newpath++;
+ }
+
+ return newpath - p; /* string length */
+}
+
void
init_header(name, v_stat, hdr)
char *name;
hdr->original_size = v_stat->st_size;
hdr->attribute = GENERIC_ATTRIBUTE;
hdr->header_level = header_level;
- len = str_safe_copy(hdr->name,
- remove_leading_dots(name),
- sizeof(hdr->name));
+
+ len = remove_dots(hdr->name, name, sizeof(hdr->name));
+
hdr->crc = 0x0000;
hdr->extend_type = EXTEND_UNIX;
hdr->unix_last_modified_stamp = v_stat->st_mtime;
--- /dev/null
+# -*- shell-script -*-
+message testing to remove relative path
+
+# remove leading "../"; this behavior will be like the GNU tar.
+
+echo -------------------------------------------------------------------
+# "../xx/xx" -> "xx/xx"
+(cd test-1 &&
+ $lha c $builddir/test-tmp-1.lzh ../test-1/test-a
+ ) 2> test-tmp-stderr
+ check $? $LINENO
+
+cat <<"EOF" | diff - test-tmp-stderr
+LHa: Warning: Removing leading `../' from member name.
+EOF
+ check $? $LINENO
+
+$lha vvq test-tmp-1.lzh | head -1
+$lha vvq test-tmp-1.lzh | head -1 | egrep '^test-1/test-a$'
+ check $? $LINENO
+
+echo -------------------------------------------------------------------
+# ../xx/../xx (result: xx not "../xx")
+(cd test-1 &&
+ $lha c $builddir/test-tmp-2.lzh ../test-1/../test-a
+ ) 2> test-tmp-stderr
+ check $? $LINENO
+
+cat <<"EOF" | diff - test-tmp-stderr
+LHa: Warning: Removing leading `../test-1/../' from member name.
+EOF
+ check $? $LINENO
+
+$lha vvq test-tmp-2.lzh | head -1
+$lha vvq test-tmp-2.lzh | head -1 | egrep '^test-a$'
+ check $? $LINENO
+echo -------------------------------------------------------------------
+# ../xx/xx/../xx (result: xx not "xx/xx")
+mkdir test-tmp-3 &&
+cp -pr test-1 test-tmp-3 &&
+cp -p test-a test-tmp-3
+ check $? $LINENO
+(cd test-tmp-3 &&
+ $lha c $builddir/test-tmp-3.lzh ../test-tmp-3/test-1/../test-a
+ ) 2> test-tmp-stderr
+ check $? $LINENO
+
+cat <<"EOF" | diff - test-tmp-stderr
+LHa: Warning: Removing leading `../test-tmp-3/test-1/../' from member name.
+EOF
+ check $? $LINENO
+
+$lha vvq test-tmp-3.lzh | head -1
+$lha vvq test-tmp-3.lzh | head -1 | egrep '^test-a$'
+ check $? $LINENO
+echo -------------------------------------------------------------------
+# just a ".." (result: ".")
+mkdir test-tmp-4 &&
+cp -pr test-1 test-tmp-4
+ check $? $LINENO
+(cd test-tmp-4/test-1 &&
+ $lha c $builddir/test-tmp-4.lzh ..
+ ) 2> test-tmp-stderr
+ check $? $LINENO
+
+cat <<"EOF" | diff - test-tmp-stderr
+LHa: Warning: Removing leading `..' from member name.
+LHa: Warning: Removing leading `../' from member name.
+LHa: Warning: Removing leading `../' from member name.
+LHa: Warning: Removing leading `../' from member name.
+LHa: Warning: Removing leading `../' from member name.
+EOF
+ check $? $LINENO
+
+$lha vvq test-tmp-4.lzh
+$lha vvq test-tmp-4.lzh > test-tmp-stdout
+ check $? $LINENO
+
+cat <<"EOF" > test-tmp-expect
+./
+test-1/
+test-1/test-a
+test-1/test-b
+test-1/test-c
+EOF
+
+egrep -v -- '-lh' test-tmp-stdout | diff - test-tmp-expect
+ check $? $LINENO
+echo -------------------------------------------------------------------
+# "xx/./xx" -> "xx/xx"
+$lha c test-tmp-5.lzh test-1/./test-a
+ check $? $LINENO
+$lha vvq test-tmp-5.lzh
+$lha vvq test-tmp-5.lzh > test-tmp-stdout
+ check $? $LINENO
+cat <<"EOF" > test-tmp-expect
+test-1/test-a
+EOF
+
+egrep -v -- '-lh' test-tmp-stdout | diff - test-tmp-expect
+ check $? $LINENO
+echo -------------------------------------------------------------------
+# "./xx/././xx" -> "xx/xx"
+$lha c test-tmp-6.lzh ./test-1/././test-a
+ check $? $LINENO
+$lha vvq test-tmp-6.lzh
+$lha vvq test-tmp-6.lzh > test-tmp-stdout
+ check $? $LINENO
+cat <<"EOF" > test-tmp-expect
+test-1/test-a
+EOF
+
+egrep -v -- '-lh' test-tmp-stdout | diff - test-tmp-expect
+ check $? $LINENO
+echo -------------------------------------------------------------------
+# "xx/./xx/./././xx" -> "xx/xx/xx"
+mkdir test-tmp-7 &&
+cp -pr test-1 test-tmp-7 &&
+cp -p test-a test-tmp-7
+ check $? $LINENO
+$lha c test-tmp-7.lzh test-tmp-7/./test-1/./././test-a
+ check $? $LINENO
+$lha vvq test-tmp-7.lzh
+$lha vvq test-tmp-7.lzh > test-tmp-stdout
+ check $? $LINENO
+cat <<"EOF" > test-tmp-expect
+test-tmp-7/test-1/test-a
+EOF
+
+egrep -v -- '-lh' test-tmp-stdout | diff - test-tmp-expect
+ check $? $LINENO
+echo -------------------------------------------------------------------
+# "./" -> "."
+(cd test-1 &&
+ $lha c $builddir/test-tmp-8.lzh ./
+ )
+ check $? $LINENO
+$lha vvq test-tmp-8.lzh
+$lha vvq test-tmp-8.lzh > test-tmp-stdout
+ check $? $LINENO
+cat <<"EOF" > test-tmp-expect
+./
+test-a
+test-b
+test-c
+EOF
+
+egrep -v -- '-lh' test-tmp-stdout | diff - test-tmp-expect
+ check $? $LINENO
+echo -------------------------------------------------------------------
+# "." -> "."
+(cd test-1 &&
+ $lha c $builddir/test-tmp-9.lzh .
+ )
+ check $? $LINENO
+$lha vvq test-tmp-9.lzh
+$lha vvq test-tmp-9.lzh > test-tmp-stdout
+ check $? $LINENO
+cat <<"EOF" > test-tmp-expect
+./
+test-a
+test-b
+test-c
+EOF
+
+egrep -v -- '-lh' test-tmp-stdout | diff - test-tmp-expect
+ check $? $LINENO
+echo -------------------------------------------------------------------