Skip to content

Commit

Permalink
More UTF-8 in paths, from Alexey Kovalenko.
Browse files Browse the repository at this point in the history
Change-Id: Ic5b75d640cd42fc4c23a30c9f2a721a95471df69
  • Loading branch information
grke committed May 27, 2017
1 parent f2eb4cf commit 9131186
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/burp.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@
// Local Burp includes. Be sure to put all the system includes before these.
#ifdef HAVE_WIN32
#include <windows.h>
#include "win32/compat/compat.h"
#endif

#include "burpconfig.h"

#ifdef HAVE_WIN32
#include "win32/compat/compat.h"
#include "win32/winapi.h"
#include "winhost.h"
#endif
Expand Down
33 changes: 29 additions & 4 deletions src/burpconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,36 @@

#define ASSERT(x)

// MAX_PATH is Windows constatnt, usually 260, maybe changed in some Win10 update.
// PATH_MAX is Posix constant
// right method - it to call pathconf(), but such case lead to reworking lots of code;
// and some buffers are better to allocate on stack, not on heap
#ifndef MAX_PATH
#ifdef PATH_MAX
#define MAX_PATH PATH_MAX
#else
#define MAX_PATH 260
#endif
#endif

// unicode enabling of win 32 needs some defines and functions

// using an average of 3 bytes per character is probably fine in
// practice but I believe that Windows actually uses UTF-16 encoding
// as opposed to UCS2 which means characters 0x10000-0x10ffff are
// valid and result in 4 byte UTF-8 encodings.
#define MAX_PATH_UTF8 MAX_PATH*4 // strict upper bound on UTF-16 to UTF-8 conversion

// from
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getfileattributesex.asp
// In the ANSI version of this function, the name is limited to
// MAX_PATH characters. To extend this limit to 32,767 wide
// characters, call the Unicode version of the function and prepend
// "\\?\" to the path. For more information, see Naming a File.
#define MAX_PATH_W 32767

#ifdef HAVE_WIN32

#define WIN32_REPARSE_POINT 1 // Any odd dir except the next two.
#define WIN32_MOUNT_POINT 2 // Directory link to Volume.
#define WIN32_JUNCTION_POINT 3 // Directory link to a directory.
Expand All @@ -24,10 +53,6 @@
#endif
#endif

#ifndef S_ISLNK
#define S_ISLNK(m) (((m) & S_IFM) == S_IFLNK)
#endif

#ifndef O_BINARY
#define O_BINARY 0
#endif
Expand Down
23 changes: 19 additions & 4 deletions src/server/protocol1/backup_phase2.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ static int path_length_warn(struct iobuf *path, struct conf **cconfs)

static int path_too_long(struct iobuf *path, struct conf **cconfs)
{
static const char *cp;
const char *cp;
const char *cp1;
size_t len;

if(treepathlen+path->len+1>fs_full_path_max)
{
// FIX THIS:
Expand All @@ -43,9 +46,21 @@ static int path_too_long(struct iobuf *path, struct conf **cconfs)
// to be able to fix it.
return path_length_warn(path, cconfs);
}
if((cp=strrchr(path->buf, '/'))) cp++;
else cp=path->buf;
if(strlen(cp)>fs_name_max) return path_length_warn(path, cconfs);
// We have to check every part in the path to ensure it less then fs_name_max
// minimum windows case is c:/a, nix case is /
// usual: c:/users, /home
cp = strchr(path->buf, '/');
if( !cp ) // very strange
return strlen(path->buf) > fs_name_max ? path_length_warn(path, cconfs):0;
while(cp && *cp)
{
cp++;
cp1 = strchr(cp, '/');
len = cp1? cp1-cp : strlen(cp);
if( len > fs_name_max )
return path_length_warn(path, cconfs);
cp = cp1;
}
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/server/protocol1/bedup.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ static int process_dir(const char *oldpath, const char *newpath,
}
ret=0;
end:
closedir(dirp);
if(dirp) closedir(dirp);
free_w(&newfile.path);
free_w(&path);
return ret;
Expand Down
4 changes: 2 additions & 2 deletions src/win32/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ $(DIRS):
exit 1 ; \
fi ; \
done ; \
ln -vsfT $${TOOLSDIR}/burp-cross-tools ../../burp-cross-tools ; \
ln -vsfT $${TOOLSDIR}/burp-depkgs ../../burp-depkgs
ln -vsf $${TOOLSDIR}/burp-cross-tools ../../burp-cross-tools ; \
ln -vsf $${TOOLSDIR}/burp-depkgs ../../burp-depkgs

Makefile.inc: ../../burp-cross-tools
@echo Creating $@
Expand Down
27 changes: 13 additions & 14 deletions src/win32/compat/compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
#include "mem_pool.h"
#include "berrno.h"

#define MAX_PATHLENGTH 1024

/* UTF-8 to UCS2 path conversion is expensive,
so we cache the conversion. During backup the
conversion is called 3 times (lstat, attribs, open),
Expand Down Expand Up @@ -1206,6 +1204,7 @@ DIR *opendir(const char *path)

int closedir(DIR *dirp)
{
if(!dirp) return 0;
_dir *dp=(_dir *)dirp;
FindClose(dp->dirh);
_dir_free(dp);
Expand All @@ -1215,7 +1214,7 @@ int closedir(DIR *dirp)
static void copyin(struct dirent *entry, const char *fname)
{
char *cp=entry->d_name;
while(*fname)
while( *fname && entry->d_reclen < (MAX_PATH_UTF8-1) )
{
*cp++=*fname++;
entry->d_reclen++;
Expand Down Expand Up @@ -1312,9 +1311,9 @@ long pathconf(const char *path, int name)
{
case _PC_PATH_MAX:
if(!strncmp(path, "\\\\?\\", 4))
return 32767;
return MAX_PATH_W;
case _PC_NAME_MAX:
return 255;
return MAX_PATH;
}
return system_error();
}
Expand Down Expand Up @@ -1783,7 +1782,7 @@ const char * getArgv0(const char *cmdline)

static int dwAltNameLength_ok(DWORD dwAltNameLength)
{
return dwAltNameLength>0 && dwAltNameLength<MAX_PATHLENGTH;
return dwAltNameLength>0 && dwAltNameLength<MAX_PATH_UTF8;
}

/* Extracts the executable or script name from the first string in
Expand Down Expand Up @@ -1883,11 +1882,11 @@ bool GetApplicationName(const char *cmdline, char **pexe, const char **pargs)
DWORD dwBasePathLength=pExeEnd-pExeStart;

DWORD dwAltNameLength=0;
char *pPathname=(char *)alloca(MAX_PATHLENGTH+1);
char *pAltPathname=(char *)alloca(MAX_PATHLENGTH+1);
char *pPathname=(char *)alloca(MAX_PATH_UTF8+1);
char *pAltPathname=(char *)alloca(MAX_PATH_UTF8+1);

pPathname[MAX_PATHLENGTH]='\0';
pAltPathname[MAX_PATHLENGTH]='\0';
pPathname[MAX_PATH_UTF8]='\0';
pAltPathname[MAX_PATH_UTF8]='\0';

memcpy(pPathname, pExeStart, dwBasePathLength);
pPathname[dwBasePathLength]='\0';
Expand All @@ -1904,7 +1903,7 @@ bool GetApplicationName(const char *cmdline, char **pexe, const char **pargs)
// There are no path separators, search in the
// standard locations
dwAltNameLength=SearchPath(NULL, pPathname,
ExtensionList[index], MAX_PATHLENGTH,
ExtensionList[index], MAX_PATH_UTF8,
pAltPathname, NULL);
if(dwAltNameLength_ok(dwAltNameLength))
{
Expand All @@ -1917,7 +1916,7 @@ bool GetApplicationName(const char *cmdline, char **pexe, const char **pargs)
else
{
snprintf(&pPathname[dwBasePathLength],
MAX_PATHLENGTH-dwBasePathLength,
MAX_PATH_UTF8-dwBasePathLength,
"%s", ExtensionList[index]);
if(GetFileAttributes(pPathname)
!=INVALID_FILE_ATTRIBUTES)
Expand All @@ -1931,7 +1930,7 @@ bool GetApplicationName(const char *cmdline, char **pexe, const char **pargs)
// There are no path separators, search in the standard
// locations.
dwAltNameLength=SearchPath(NULL, pPathname,
NULL, MAX_PATHLENGTH, pAltPathname, NULL);
NULL, MAX_PATH_UTF8, pAltPathname, NULL);
if(dwAltNameLength_ok(dwAltNameLength))
{
memcpy(pPathname, pAltPathname, dwAltNameLength);
Expand All @@ -1942,7 +1941,7 @@ bool GetApplicationName(const char *cmdline, char **pexe, const char **pargs)
if(strchr(pPathname, ' '))
{
dwAltNameLength=GetShortPathName(pPathname,
pAltPathname, MAX_PATHLENGTH);
pAltPathname, MAX_PATH_UTF8);

if(dwAltNameLength_ok(dwAltNameLength))
{
Expand Down
5 changes: 1 addition & 4 deletions src/win32/compat/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,7 @@ struct dirent
uint64_t d_ino;
uint32_t d_off;
uint16_t d_reclen;
// MAX_PATH_UTF8 is MAX_PATH*4, but I have had problems trying to
// include winapi.h so that it is seen here. Do it manually here, and
// add a bit more just in case.
char d_name[(MAX_PATH*4)+16];
char d_name[MAX_PATH_UTF8];
};
typedef void DIR;

Expand Down
16 changes: 3 additions & 13 deletions src/win32/winapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,9 @@

// unicode enabling of win 32 needs some defines and functions

// using an average of 3 bytes per character is probably fine in
// practice but I believe that Windows actually uses UTF-16 encoding
// as opposed to UCS2 which means characters 0x10000-0x10ffff are
// valid and result in 4 byte UTF-8 encodings.
#define MAX_PATH_UTF8 MAX_PATH*4 // strict upper bound on UTF-16 to UTF-8 conversion

// from
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getfileattributesex.asp
// In the ANSI version of this function, the name is limited to
// MAX_PATH characters. To extend this limit to 32,767 wide
// characters, call the Unicode version of the function and prepend
// "\\?\" to the path. For more information, see Naming a File.
#define MAX_PATH_W 32767
// MAX_PATH_UTF8 moved to burpconfig.h
// winapi.h used only in burp.h just after using burpconfig.h
#include "burpconfig.h"

int wchar_2_UTF8(char *pszUTF, const WCHAR *pszUCS, int cchChar = MAX_PATH_UTF8);
int UTF8_2_wchar(char **pszUCS, const char *pszUTF);
Expand Down

0 comments on commit 9131186

Please sign in to comment.