Hello community,
here is the log from the commit of package cabextract for openSUSE:Factory checked in at 2015-04-03 14:34:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cabextract (Old)
and /work/SRC/openSUSE:Factory/.cabextract.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cabextract"
Changes:
--------
--- /work/SRC/openSUSE:Factory/cabextract/cabextract.changes 2015-02-22 17:26:50.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.cabextract.new/cabextract.changes 2015-04-03 14:34:52.000000000 +0200
@@ -1,0 +2,8 @@
+Thu Apr 2 16:51:12 CEST 2015 - sbrabec@suse.cz
+
+- Update to version 1.6:
+ * further UTF-8 fixes
+ * sanitize file names
+- Add -fno-strict-aliasing for md5.c: 114, 115.
+
+-------------------------------------------------------------------
Old:
----
cabextract-1.5.tar.gz
New:
----
cabextract-1.6.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ cabextract.spec ++++++
--- /var/tmp/diff_new_pack.XjPSG1/_old 2015-04-03 14:34:53.000000000 +0200
+++ /var/tmp/diff_new_pack.XjPSG1/_new 2015-04-03 14:34:53.000000000 +0200
@@ -17,7 +17,7 @@
Name: cabextract
-Version: 1.5
+Version: 1.6
Release: 0
Summary: A Program to Extract Microsoft Cabinet Files
License: GPL-3.0+
@@ -36,7 +36,7 @@
%setup -q
%build
-CFLAGS="%{optflags} -fPIE"
+CFLAGS="%{optflags} -fPIE -fno-strict-aliasing"
%configure --with-external-libmspack
make %{?_smp_mflags} LDFLAGS="-pie"
++++++ cabextract-1.5.tar.gz -> cabextract-1.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/ChangeLog new/cabextract-1.6/ChangeLog
--- old/cabextract-1.5/ChangeLog 2015-01-18 16:58:40.000000000 +0100
+++ new/cabextract-1.6/ChangeLog 2015-02-26 11:51:11.000000000 +0100
@@ -1,3 +1,18 @@
+2015-02-25 Stuart Caie
+
+ * create_output_name(): Simplify code; do path checking only after
+ output name has been constructed. Use towlower to lowercase UTF-8
+ characters. Remove both leading '/' and '\' from cab filenames and
+ change both "../" and "..\" to "xx", for Cygwin and other Cygwin-like
+ environments that use both '/' and '\' as path separators. Thanks to
+ Alexander Cherepanov and the MITRE team.
+
+2015-02-18 Stuart Caie
+
+ * create_output_name(): the check against leading slashes could be
+ evaded with malformed UTF-8. Thanks to Alexander Cherepanov for
+ reporting the issue.
+
2015-01-18 Stuart Caie
* wince_rename: installed files now include their install directories.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/Makefile.in new/cabextract-1.6/Makefile.in
--- old/cabextract-1.5/Makefile.in 2015-01-24 14:23:03.000000000 +0100
+++ new/cabextract-1.6/Makefile.in 2015-03-23 00:26:42.000000000 +0100
@@ -84,8 +84,8 @@
DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog COPYING \
$(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
- $(srcdir)/config.h.in $(srcdir)/cabextract.spec.in getopt1.c \
- getopt.c mktime.c fnmatch.c TODO compile install-sh missing
+ $(srcdir)/config.h.in $(srcdir)/cabextract.spec.in mktime.c \
+ getopt.c getopt1.c fnmatch.c TODO compile install-sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/NEWS new/cabextract-1.6/NEWS
--- old/cabextract-1.5/NEWS 2015-01-24 13:55:29.000000000 +0100
+++ new/cabextract-1.6/NEWS 2015-02-26 11:28:44.000000000 +0100
@@ -1,3 +1,12 @@
+New in 1.6
+* cabextract now prevents archive files giving themselves absolute path access
+ using badly UTF-8 encoded slashes.
+* Because Cygwin allows both '/' and '\' as path separators, cabextract now
+ removes both leading '/'s and '\'s and changes both "../" and "..\" in
+ CAB filenames to "xx". You can no longer have a CAB filename called e.g
+ "\/t" (file "t" in the directory "\"). If you need this, create a CAB file
+ where the filename is "./\/t" instead.
+
New in 1.5
* cabextract replaces bad Unicode characters in filenames with the
standard Unicode replacement character
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/README new/cabextract-1.6/README
--- old/cabextract-1.5/README 2015-01-24 13:56:18.000000000 +0100
+++ new/cabextract-1.6/README 2015-03-23 00:21:25.000000000 +0100
@@ -1,4 +1,4 @@
-cabextract 1.5 - a program to extract Microsoft Cabinet files.
+cabextract 1.6 - a program to extract Microsoft Cabinet files.
(C) 2000-2015 Stuart Caie
This is free software with ABSOLUTELY NO WARRANTY.
@@ -42,4 +42,4 @@
Testing the integrity of a cabinet file, without extracting it:
$ cabextract -t wibble.cab
-Stuart Caie , January 2015
+Stuart Caie , March 2015
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/cabextract.spec new/cabextract-1.6/cabextract.spec
--- old/cabextract-1.5/cabextract.spec 2015-01-24 14:23:09.000000000 +0100
+++ new/cabextract-1.6/cabextract.spec 2015-03-23 00:26:48.000000000 +0100
@@ -1,6 +1,6 @@
Summary: A program to extract Microsoft Cabinet files
Name: cabextract
-Version: 1.5
+Version: 1.6
Release: 1
License: GPL
Group: Applications/Archiving
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/config.h.in new/cabextract-1.6/config.h.in
--- old/cabextract-1.5/config.h.in 2015-01-24 14:23:02.000000000 +0100
+++ new/cabextract-1.6/config.h.in 2015-03-23 00:26:40.000000000 +0100
@@ -68,6 +68,9 @@
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
/* Define to 1 if you have the header file. */
#undef HAVE_MEMORY_H
@@ -118,6 +121,9 @@
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the `towlower' function. */
+#undef HAVE_TOWLOWER
+
/* Define to 1 if you have the header file. */
#undef HAVE_UNISTD_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/configure new/cabextract-1.6/configure
--- old/cabextract-1.5/configure 2015-01-24 14:23:02.000000000 +0100
+++ new/cabextract-1.6/configure 2015-03-23 00:26:40.000000000 +0100
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for cabextract 1.5.
+# Generated by GNU Autoconf 2.69 for cabextract 1.6.
#
# Report bugs to .
#
@@ -579,8 +579,8 @@
# Identity of this package.
PACKAGE_NAME='cabextract'
PACKAGE_TARNAME='cabextract'
-PACKAGE_VERSION='1.5'
-PACKAGE_STRING='cabextract 1.5'
+PACKAGE_VERSION='1.6'
+PACKAGE_STRING='cabextract 1.6'
PACKAGE_BUGREPORT='kyzer@4u.net'
PACKAGE_URL=''
@@ -1274,7 +1274,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures cabextract 1.5 to adapt to many kinds of systems.
+\`configure' configures cabextract 1.6 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1340,7 +1340,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of cabextract 1.5:";;
+ short | recursive ) echo "Configuration of cabextract 1.6:";;
esac
cat <<\_ACEOF
@@ -1438,7 +1438,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-cabextract configure 1.5
+cabextract configure 1.6
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2090,7 +2090,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by cabextract $as_me 1.5, which was
+It was created by cabextract $as_me 1.6, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2956,7 +2956,7 @@
# Define the identity of the package.
PACKAGE='cabextract'
- VERSION='1.5'
+ VERSION='1.6'
cat >>confdefs.h <<_ACEOF
@@ -4781,7 +4781,7 @@
for ac_header in ctype.h errno.h fnmatch.h libintl.h limits.h stdlib.h \
string.h strings.h utime.h stdarg.h sys/stat.h sys/time.h sys/types.h \
- getopt.h wchar.h wctype.h
+ getopt.h wchar.h wctype.h inttypes.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -5618,7 +5618,7 @@
fi
-for ac_func in memcpy strcasecmp strchr utime utimes
+for ac_func in memcpy memmove strcasecmp strchr towlower utime utimes
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -6626,7 +6626,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by cabextract $as_me 1.5, which was
+This file was extended by cabextract $as_me 1.6, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -6696,7 +6696,7 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-cabextract config.status 1.5
+cabextract config.status 1.6
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/configure.ac new/cabextract-1.6/configure.ac
--- old/cabextract-1.5/configure.ac 2015-01-24 13:56:31.000000000 +0100
+++ new/cabextract-1.6/configure.ac 2015-02-26 11:52:22.000000000 +0100
@@ -1,7 +1,7 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
-AC_INIT(cabextract, 1.5, kyzer@4u.net)
+AC_INIT(cabextract, 1.6, kyzer@4u.net)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src/cabextract.c])
AC_CONFIG_HEADER([config.h])
@@ -18,7 +18,7 @@
AC_HEADER_DIRENT
AC_CHECK_HEADERS([ctype.h errno.h fnmatch.h libintl.h limits.h stdlib.h \
string.h strings.h utime.h stdarg.h sys/stat.h sys/time.h sys/types.h \
- getopt.h wchar.h wctype.h])
+ getopt.h wchar.h wctype.h inttypes.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@@ -34,7 +34,7 @@
AC_FUNC_FSEEKO
AX_FUNC_MKDIR
AC_FUNC_MKTIME
-AC_CHECK_FUNCS([memcpy strcasecmp strchr utime utimes])
+AC_CHECK_FUNCS([memcpy memmove strcasecmp strchr towlower utime utimes])
AC_CHECK_FUNCS([getopt_long],,[AC_CHECK_LIB([gnugetopt], [getopt_long],
[AC_DEFINE([HAVE_GETOPT_LONG])],[AC_LIBOBJ(getopt) AC_LIBOBJ(getopt1)])])
AC_REPLACE_FNMATCH
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/mspack/ChangeLog new/cabextract-1.6/mspack/ChangeLog
--- old/cabextract-1.5/mspack/ChangeLog 2015-01-19 00:11:15.000000000 +0100
+++ new/cabextract-1.6/mspack/ChangeLog 2015-01-30 01:00:05.000000000 +0100
@@ -1,3 +1,8 @@
+2015-01-29 Stuart Caie
+
+ * system.h: if C99 inttypes.h exists, use its PRI{d,u}{32,64} macros.
+ Thanks to Johnathan Kollasch for the suggestion.
+
2015-01-18 Stuart Caie
* lzxd_decompress(): the byte-alignment code for reading uncompressed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/mspack/system.h new/cabextract-1.6/mspack/system.h
--- old/cabextract-1.5/mspack/system.h 2011-04-26 19:15:21.000000000 +0200
+++ new/cabextract-1.6/mspack/system.h 2015-01-30 00:58:32.000000000 +0100
@@ -57,17 +57,26 @@
# include
#endif
+#ifdef HAVE_INTTYPES_H
+# include
+#else
+# define PRId64 "lld"
+# define PRIu64 "llu"
+# define PRId32 "ld"
+# define PRIu32 "lu"
+#endif
+
#if ((defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS >= 64) || \
(defined(FILESIZEBITS) && FILESIZEBITS >= 64) || \
(defined(SIZEOF_OFF_T) && SIZEOF_OFF_T >= 8) || \
defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE))
# define LARGEFILE_SUPPORT
-# define LD "lld"
-# define LU "llu"
+# define LD PRId64
+# define LU PRIu64
#else
extern const char *largefile_msg;
-# define LD "ld"
-# define LU "lu"
+# define LD PRId32
+# define LU PRIu32
#endif
/* endian-neutral reading of little-endian data */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cabextract-1.5/src/cabextract.c new/cabextract-1.6/src/cabextract.c
--- old/cabextract-1.5/src/cabextract.c 2015-01-10 19:13:11.000000000 +0100
+++ new/cabextract-1.6/src/cabextract.c 2015-02-26 11:53:01.000000000 +0100
@@ -1,5 +1,5 @@
-/* cabextract 1.4 - a program to extract Microsoft Cabinet files
- * (C) 2000-2011 Stuart Caie
+/* cabextract 1.6 - a program to extract Microsoft Cabinet files
+ * (C) 2000-2015 Stuart Caie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,6 +35,10 @@
# include
#endif
+#if HAVE_WCTYPE_H
+# include
+#endif
+
#if HAVE_ERRNO_H
# include
#endif
@@ -112,6 +116,9 @@
# if !HAVE_MEMCPY
# define memcpy(d,s,n) bcopy((s),(d),(n))
# endif
+# if !HAVE_MEMMOVE
+# define memmove(d,s,n) bcopy((s),(d),(n))
+# endif
#endif
#if HAVE_MKDIR
@@ -212,7 +219,7 @@
char *basename);
static char *find_cabinet_file(char *origcab, char *cabname);
static int unix_path_seperators(struct mscabd_file *files);
-static char *create_output_name(unsigned char *fname, unsigned char *dir,
+static char *create_output_name(const char *fname, const char *dir,
int lower, int isunix, int unicode);
static void set_date_and_perm(struct mscabd_file *file, char *filename);
@@ -441,8 +448,7 @@
/* process all files */
for (file = cab->files; file; file = file->next) {
/* create the full UNIX output filename */
- if (!(name = create_output_name(
- (unsigned char *) file->filename, (unsigned char *) args.dir,
+ if (!(name = create_output_name(file->filename, args.dir,
args.lower, isunix, file->attribs & MSCAB_ATTRIB_UTF_NAME)))
{
errors++;
@@ -735,77 +741,62 @@
* not enough memory.
* @see unix_path_seperators()
*/
-static char *create_output_name(unsigned char *fname, unsigned char *dir,
- int lower, int isunix, int utf8)
+static char *create_output_name(const char *fname, const char *dir,
+ int lower, int isunix, int utf8)
{
- unsigned char *p, *name, c, *fe, sep, slash;
- int x;
+ char sep = (isunix) ? '/' : '\\'; /* the path-seperator */
+ char slash = (isunix) ? '\\' : '/'; /* the other slash */
+
+ size_t dirlen = dir ? strlen(dir) + 1 : 0; /* length of dir + '/' */
+ size_t filelen = strlen(fname);
- sep = (isunix) ? '/' : '\\'; /* the path-seperator */
- slash = (isunix) ? '\\' : '/'; /* the other slash */
+ /* worst case, UTF-8 processing expands all chars to 4 bytes */
+ char *name = malloc(dirlen + (filelen * 4) + 2);
- /* length of filename */
- x = strlen((char *) fname);
- /* UTF-8 worst case scenario: tolower() expands all chars from 1 to 4 bytes */
- if (utf8) x *= 4;
- /* length of output directory */
- if (dir) x += strlen((char *) dir);
- x += 2;
+ unsigned char *i = (unsigned char *) &fname[0];
+ unsigned char *iend = (unsigned char *) &fname[filelen];
+ unsigned char *o = (unsigned char *) &name[dirlen], c;
- if (!(name = malloc(x))) {
- fprintf(stderr, "Can't allocate output filename (%u bytes)\n", x);
+ if (!name) {
+ fprintf(stderr, "Can't allocate output filename\n");
return NULL;
}
-
- /* start with blank name */
- *name = '\0';
- /* add output directory if needed */
+ /* copy directory prefix if needed */
if (dir) {
- strcpy((char *) name, (char *) dir);
- strcat((char *) name, "/");
+ strcpy(name, dir);
+ name[dirlen - 1] = '/';
}
- /* remove leading slashes */
- while (*fname == sep) fname++;
-
- /* copy from fi->filename to new name, converting MS-DOS slashes to UNIX
- * slashes as we go. Also lowercases characters if needed.
- */
- p = &name[strlen((char *)name)]; /* p = start of output filename */
- fe = &fname[strlen((char *)fname)]; /* fe = end of input filename */
-
+ /* copy cab filename to output name, converting MS-DOS slashes to UNIX
+ * slashes as we go. Also lowercases characters if needed. */
if (utf8) {
/* handle UTF-8 encoded filenames (see RFC 3629). This doesn't reject bad
- * UTF-8 with overlong encodings, but does re-encode it as valid UTF-8.
- */
- while (fname < fe) {
+ * UTF-8 with overlong encodings, but does re-encode it as valid UTF-8. */
+ while (i < iend) {
/* get next UTF-8 character */
- if ((c = *fname++) < 0x80) {
+ int x;
+ if ((c = *i++) < 0x80) {
x = c;
}
- else if (c >= 0xC2 && c < 0xE0 && fname <= fe &&
- (fname[0] & 0xC0) == 0x80)
- {
+ else if (c >= 0xC2 && c < 0xE0 && i <= iend && (i[0] & 0xC0) == 0x80) {
x = (c & 0x1F) << 6;
- x |= *fname++ & 0x3F;
+ x |= *i++ & 0x3F;
}
- else if (c >= 0xE0 && c < 0xF0 && fname+1 <= fe &&
- (fname[0] & 0xC0) == 0x80 && (fname[1] & 0xC0) == 0x80)
+ else if (c >= 0xE0 && c < 0xF0 && i+1 <= iend && (i[0] & 0xC0) == 0x80 &&
+ (i[1] & 0xC0) == 0x80)
{
x = (c & 0x0F) << 12;
- x |= (*fname++ & 0x3F) << 6;
- x |= *fname++ & 0x3F;
+ x |= (*i++ & 0x3F) << 6;
+ x |= *i++ & 0x3F;
}
- else if (c >= 0xF0 && c < 0xF5 && fname+2 <= fe &&
- (fname[0] & 0xC0) == 0x80 &&
- (fname[1] & 0xC0) == 0x80 &&
- (fname[2] & 0xC0) == 0x80)
+ else if (c >= 0xF0 && c < 0xF5 && i+2 <= iend && (i[0] & 0xC0) == 0x80 &&
+ (i[1] & 0xC0) == 0x80 && (i[2] & 0xC0) == 0x80)
{
x = (c & 0x07) << 18;
- x |= (*fname++ & 0x3F) << 12;
- x |= (*fname++ & 0x3F) << 6;
- x |= *fname++ & 0x3F;
+ x |= (*i++ & 0x3F) << 12;
+ x |= (*i++ & 0x3F) << 6;
+ x |= *i++ & 0x3F;
}
else {
x = 0xFFFD; /* unicode replacement character */
@@ -815,60 +806,78 @@
x = 0xFFFD; /* invalid code point or cheeky null byte */
}
- /* whatever is the path seperator -> '/'
- * whatever is the other slash -> '\\'
- * otherwise, if lower is set, the lowercase version */
- if (x == sep) x = '/';
- else if (x == slash) x = '\\';
- else if (lower) x = tolower(x);
+#ifdef HAVE_TOWLOWER
+ if (lower) x = towlower(x);
+#else
+ if (lower && x < 256) x = tolower(x);
+#endif
+
+ /* whatever is the path separator -> '/'
+ * whatever is the other slash -> '\' */
+ if (x == sep) x = '/'; else if (x == slash) x = '\\';
/* convert unicode character back to UTF-8 */
if (x < 0x80) {
- *p++ = (unsigned char) x;
+ *o++ = (unsigned char) x;
}
else if (x < 0x800) {
- *p++ = 0xC0 | (x >> 6);
- *p++ = 0x80 | (x & 0x3F);
+ *o++ = 0xC0 | (x >> 6);
+ *o++ = 0x80 | (x & 0x3F);
}
else if (x < 0x10000) {
- *p++ = 0xE0 | (x >> 12);
- *p++ = 0x80 | ((x >> 6) & 0x3F);
- *p++ = 0x80 | (x & 0x3F);
+ *o++ = 0xE0 | (x >> 12);
+ *o++ = 0x80 | ((x >> 6) & 0x3F);
+ *o++ = 0x80 | (x & 0x3F);
}
else if (x <= 0x10FFFF) {
- *p++ = 0xF0 | (x >> 18);
- *p++ = 0x80 | ((x >> 12) & 0x3F);
- *p++ = 0x80 | ((x >> 6) & 0x3F);
- *p++ = 0x80 | (x & 0x3F);
+ *o++ = 0xF0 | (x >> 18);
+ *o++ = 0x80 | ((x >> 12) & 0x3F);
+ *o++ = 0x80 | ((x >> 6) & 0x3F);
+ *o++ = 0x80 | (x & 0x3F);
}
else {
- *p++ = 0xEF; /* unicode replacement character in UTF-8 */
- *p++ = 0xBF;
- *p++ = 0xBD;
+ *o++ = 0xEF; /* unicode replacement character in UTF-8 */
+ *o++ = 0xBF;
+ *o++ = 0xBD;
}
}
- *p++ = 0;
}
else {
- /* regular non-utf8 version */
- do {
- c = *fname++;
- if (c == sep) c = '/';
- else if (c == slash) c = '\\';
- else if (lower) c = (unsigned char) tolower((int) c);
- } while ((*p++ = c));
+ /* non UTF-8 version */
+ while (i < iend) {
+ c = *i++;
+ if (lower) c = (unsigned char) tolower((int) c);
+ if (c == sep) c = '/'; else if (c == slash) c = '\\';
+ *o++ = c;
+ }
+ }
+ *o++ = '\0';
+
+ /* remove any leading slashes in the cab filename part.
+ * This prevents unintended absolute file path access. */
+ o = (unsigned char *) &name[dirlen];
+ for (i = o; *i == '/' || *i == '\\'; i++);
+ if (i != o) {
+ size_t len = strlen((char *) i);
+ if (len > 0) {
+ memmove(o, i, len + 1);
+ }
+ else {
+ /* change filename composed entirely of leading slashes to "x" */
+ strcpy((char *) o, "x");
+ }
}
- /* search for "../" in cab filename part and change to "xx/". This
- * prevents any unintended directory traversal. */
- for (p = &name[dir ? strlen((char *) dir)+1 : 0]; *p; p++) {
- if ((p[0] == '.') && (p[1] == '.') && (p[2] == '/')) {
- p[0] = p[1] = 'x';
- p += 2;
+ /* search for "../" or "..\" in cab filename part and change to "xx"
+ * This prevents unintended directory traversal. */
+ for (; *o; o++) {
+ if ((o[0] == '.') && (o[1] == '.') && (o[2] == '/' || o[2] == '\\')) {
+ o[0] = o[1] = 'x';
+ o += 2;
}
}
- return (char *) name;
+ return name;
}
/**