From 3583c70d3f974164e467b680891941b53afdb1c5 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Sun, 26 Apr 2020 01:53:20 +0000 Subject: Support very long input path name, longer than _MAX_PATH for Windows, if it really exists, and given an absolute path in a command line (Windows only) git-svn-id: svn://tug.org/texlive/trunk@54881 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/kpathsea/ChangeLog | 7 +++++ Build/source/texk/kpathsea/knj.c | 56 +++++++++++++++++++++++++++++++---- Build/source/texk/kpathsea/readable.c | 29 +++++++++++++++++- 3 files changed, 86 insertions(+), 6 deletions(-) (limited to 'Build/source/texk/kpathsea') diff --git a/Build/source/texk/kpathsea/ChangeLog b/Build/source/texk/kpathsea/ChangeLog index 7e8ea6c795f..1a0bc71088a 100644 --- a/Build/source/texk/kpathsea/ChangeLog +++ b/Build/source/texk/kpathsea/ChangeLog @@ -1,3 +1,10 @@ +2020-04-26 Akira Kakuto + + * readable.c, knj.c: Support very long input path name, + longer than _MAX_PATH for Windows, if it really exists and + input name is given in full-absolute path in a command line. + (Windows only). + 2020-04-10 Karl Berry * version.ac: now 6.3.3/dev since TL'20 is released. diff --git a/Build/source/texk/kpathsea/knj.c b/Build/source/texk/kpathsea/knj.c index 6db6262161f..b4595207aab 100644 --- a/Build/source/texk/kpathsea/knj.c +++ b/Build/source/texk/kpathsea/knj.c @@ -116,12 +116,35 @@ kpathsea_fsyscp_xfopen (kpathsea kpse, const char *filename, const char *mode) FILE *f; wchar_t *fnamew, modew[4]; int i; - + unsigned char *fnn; + unsigned char *p; assert(filename && mode); - - fnamew = get_wstring_from_mbstring(kpse->File_system_codepage, filename, fnamew=NULL); +/* + Support very long input path name, longer than _MAX_PATH for + Windows, if it really exists and input name is given in + full-absolute path in a command line. +*/ + fnn = xmalloc(strlen(filename) + 10); + if ((filename[0] == '/' && filename[1] == '/') || + (filename[0] == '\\' && filename[1] == '\\')) { + filename += 2; + strcpy (fnn, "\\\\?\\UNC\\"); + strcat (fnn, filename); + } else if (filename[1] == ':') { + strcpy (fnn, "\\\\?\\"); + strcat (fnn, filename); + } else { + strcpy (fnn, filename); + } + for (p = fnn; *p; p++) { + if (*p == '/') + *p = '\\'; + } + + fnamew = get_wstring_from_mbstring(kpse->File_system_codepage, fnn, fnamew=NULL); for(i=0; (modew[i]=(wchar_t)mode[i]); i++) {} /* mode[i] must be ASCII */ f = _wfopen(fnamew, modew); + free (fnn); if (f == NULL) FATAL_PERROR(filename); if (KPATHSEA_DEBUG_P (KPSE_DEBUG_FOPEN)) { @@ -149,12 +172,35 @@ kpathsea_fsyscp_fopen (kpathsea kpse, const char *filename, const char *mode) FILE *f; wchar_t *fnamew, modew[4]; int i; - + unsigned char *fnn; + unsigned char *p; assert(filename && mode); +/* + Support very long input path name, longer than _MAX_PATH for + Windows, if it really exists and input name is given in + full-absolute path in a command line. +*/ + fnn = xmalloc(strlen(filename) + 10); + if ((filename[0] == '/' && filename[1] == '/') || + (filename[0] == '\\' && filename[1] == '\\')) { + filename += 2; + strcpy (fnn, "\\\\?\\UNC\\"); + strcat (fnn, filename); + } else if (filename[1] == ':') { + strcpy (fnn, "\\\\?\\"); + strcat (fnn, filename); + } else { + strcpy (fnn, filename); + } + for (p = fnn; *p; p++) { + if (*p == '/') + *p = '\\'; + } - fnamew = get_wstring_from_mbstring(kpse->File_system_codepage, filename, fnamew=NULL); + fnamew = get_wstring_from_mbstring(kpse->File_system_codepage, fnn, fnamew=NULL); for(i=0; (modew[i]=(wchar_t)mode[i]); i++) {} /* mode[i] must be ASCII */ f = _wfopen(fnamew, modew); + free (fnn); if (f != NULL) { if (KPATHSEA_DEBUG_P (KPSE_DEBUG_FOPEN)) { DEBUGF_START (); diff --git a/Build/source/texk/kpathsea/readable.c b/Build/source/texk/kpathsea/readable.c index 2623fd2b84f..2d060d08cb4 100644 --- a/Build/source/texk/kpathsea/readable.c +++ b/Build/source/texk/kpathsea/readable.c @@ -41,7 +41,33 @@ static boolean READABLE(kpathsea kpse, const_string fn, unsigned int st) { wchar_t *fnw; - fnw = get_wstring_from_mbstring(kpse->File_system_codepage, fn, fnw=NULL); + unsigned char *fnn; + unsigned char *p; + + fnn = xmalloc(strlen(fn) + 10); +/* + Support very long input path name, longer than _MAX_PATH for + Windows, if it really exists and input name is given in + full-absolute path in a command line. +*/ + if ((fn[0] == '/' && fn[1] == '/') || + (fn[0] == '\\' && fn[1] == '\\')) { + fn += 2; + strcpy (fnn, "\\\\?\\UNC\\"); + strcat (fnn, fn); + } else if (fn[1] == ':') { + strcpy (fnn, "\\\\?\\"); + strcat (fnn, fn); + } else { + strcpy (fnn, fn); + } + + for (p = fnn; *p; p++) { + if (*p == '/') + *p = '\\'; + } + + fnw = get_wstring_from_mbstring(kpse->File_system_codepage, fnn, fnw=NULL); if ((st = GetFileAttributesW(fnw)) != 0xFFFFFFFF) { /* succeeded */ errno = 0; @@ -58,6 +84,7 @@ READABLE(kpathsea kpse, const_string fn, unsigned int st) break; } } + free (fnn); if (fnw) free (fnw); return ((st != 0xFFFFFFFF) && !(st & FILE_ATTRIBUTE_DIRECTORY)); -- cgit v1.2.3