@@ -56,6 +56,8 @@ namespace Sass {
56
56
#ifndef _WIN32
57
57
char wd[wd_len];
58
58
char * pwd = getcwd (wd, wd_len);
59
+ // we should check error for more detailed info (e.g. ENOENT)
60
+ // http://man7.org/linux/man-pages/man2/getcwd.2.html#ERRORS
59
61
if (pwd == NULL ) throw Exception::OperationError (" cwd gone missing" );
60
62
std::string cwd = pwd;
61
63
#else
@@ -74,11 +76,15 @@ namespace Sass {
74
76
bool file_exists (const std::string& path)
75
77
{
76
78
#ifdef _WIN32
79
+ wchar_t resolved[32768 ];
77
80
// windows unicode filepaths are encoded in utf16
78
81
std::string abspath (join_paths (get_cwd (), path));
79
82
std::wstring wpath (UTF_8::convert_to_utf16 (" \\\\ ?\\ " + abspath));
80
83
std::replace (wpath.begin (), wpath.end (), ' /' , ' \\ ' );
81
- DWORD dwAttrib = GetFileAttributesW (wpath.c_str ());
84
+ DWORD rv = GetFullPathNameW (wpath.c_str (), 32767 , resolved, NULL );
85
+ if (rv > 32767 ) throw Exception::OperationError (" Path is too long" );
86
+ if (rv == 0 ) throw Exception::OperationError (" Path could not be resolved" );
87
+ DWORD dwAttrib = GetFileAttributesW (resolved);
82
88
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
83
89
(!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)));
84
90
#else
@@ -200,6 +206,13 @@ namespace Sass {
200
206
if (is_absolute_path (r)) return r;
201
207
if (l[l.length ()-1 ] != ' /' ) l += ' /' ;
202
208
209
+ // this does a logical cleanup of the right hand path
210
+ // Note that this does collapse x/../y sections into y.
211
+ // This is by design. If /foo on your system is a symlink
212
+ // to /bar/baz, then /foo/../cd is actually /bar/cd,
213
+ // not /cd as a naive ../ removal would give you.
214
+ // will only work on leading double dot dirs on rhs
215
+ // therefore it is safe if lhs is already resolved cwd
203
216
while ((r.length () > 3 ) && ((r.substr (0 , 3 ) == " ../" ) || (r.substr (0 , 3 )) == " ..\\ " )) {
204
217
size_t L = l.length (), pos = find_last_folder_separator (l, L - 2 );
205
218
bool is_slash = pos + 2 == L && (l[pos+1 ] == ' /' || l[pos+1 ] == ' \\ ' );
@@ -395,11 +408,15 @@ namespace Sass {
395
408
#ifdef _WIN32
396
409
BYTE* pBuffer;
397
410
DWORD dwBytes;
411
+ wchar_t resolved[32768 ];
398
412
// windows unicode filepaths are encoded in utf16
399
413
std::string abspath (join_paths (get_cwd (), path));
400
414
std::wstring wpath (UTF_8::convert_to_utf16 (" \\\\ ?\\ " + abspath));
401
415
std::replace (wpath.begin (), wpath.end (), ' /' , ' \\ ' );
402
- HANDLE hFile = CreateFileW (wpath.c_str (), GENERIC_READ, FILE_SHARE_READ, NULL , OPEN_EXISTING, 0 , NULL );
416
+ DWORD rv = GetFullPathNameW (wpath.c_str (), 32767 , resolved, NULL );
417
+ if (rv > 32767 ) throw Exception::OperationError (" Path is too long" );
418
+ if (rv == 0 ) throw Exception::OperationError (" Path could not be resolved" );
419
+ HANDLE hFile = CreateFileW (resolved, GENERIC_READ, FILE_SHARE_READ, NULL , OPEN_EXISTING, 0 , NULL );
403
420
if (hFile == INVALID_HANDLE_VALUE) return 0 ;
404
421
DWORD dwFileLength = GetFileSize (hFile, NULL );
405
422
if (dwFileLength == INVALID_FILE_SIZE) return 0 ;
0 commit comments