Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3842529

Browse files
committed
Issue #9908: Fix os.stat() on bytes paths under Windows 7.
1 parent 3e62f78 commit 3842529

3 files changed

Lines changed: 44 additions & 19 deletions

File tree

Lib/test/test_os.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,12 @@ def tearDown(self):
219219
os.unlink(self.fname)
220220
os.rmdir(support.TESTFN)
221221

222-
def test_stat_attributes(self):
222+
def check_stat_attributes(self, fname):
223223
if not hasattr(os, "stat"):
224224
return
225225

226226
import stat
227-
result = os.stat(self.fname)
227+
result = os.stat(fname)
228228

229229
# Make sure direct access works
230230
self.assertEquals(result[stat.ST_SIZE], 3)
@@ -281,6 +281,15 @@ def trunc(x): return x
281281
except TypeError:
282282
pass
283283

284+
def test_stat_attributes(self):
285+
self.check_stat_attributes(self.fname)
286+
287+
def test_stat_attributes_bytes(self):
288+
try:
289+
fname = self.fname.encode(sys.getfilesystemencoding())
290+
except UnicodeEncodeError:
291+
self.skipTest("cannot encode %a for the filesystem" % self.fname)
292+
self.check_stat_attributes(fname)
284293

285294
def test_statvfs_attributes(self):
286295
if not hasattr(os, "statvfs"):

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ Core and Builtins
5858
Library
5959
-------
6060

61+
- Issue #9908: Fix os.stat() on bytes paths under Windows 7.
62+
6163
- Issue #2643: msync() is not called anymore when deallocating an open mmap
6264
object, only munmap().
6365

Modules/posixmodule.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,7 @@ win32_stat(const char* path, struct win32_stat *result)
11521152
NULL, /* security attributes */
11531153
OPEN_EXISTING,
11541154
/* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1155-
FILE_FLAG_BACKUP_SEMANTICS,
1155+
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
11561156
NULL);
11571157

11581158
if(hFile == INVALID_HANDLE_VALUE) {
@@ -1175,22 +1175,32 @@ win32_stat(const char* path, struct win32_stat *result)
11751175
}
11761176
code = attribute_data_to_stat(&info, result);
11771177
}
1178-
1179-
buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
1180-
if(!buf_size) return -1;
1181-
target_path = (char *)malloc((buf_size+1)*sizeof(char));
1182-
result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
1183-
buf_size, VOLUME_NAME_DOS);
1184-
1185-
if(!result_length)
1186-
return -1;
1178+
else {
1179+
/* We have a good handle to the target, use it to determine the target
1180+
path name (then we'll call lstat on it). */
1181+
buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
1182+
if(!buf_size) return -1;
1183+
/* Due to a slight discrepancy between GetFinalPathNameByHandleA
1184+
and GetFinalPathNameByHandleW, we must allocate one more byte
1185+
than reported. */
1186+
target_path = (char *)malloc((buf_size+2)*sizeof(char));
1187+
result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
1188+
buf_size+1, VOLUME_NAME_DOS);
1189+
1190+
if(!result_length) {
1191+
free(target_path);
1192+
return -1;
1193+
}
11871194

1188-
if(!CloseHandle(hFile))
1189-
return -1;
1195+
if(!CloseHandle(hFile)) {
1196+
free(target_path);
1197+
return -1;
1198+
}
11901199

1191-
target_path[result_length] = 0;
1192-
code = win32_lstat(target_path, result);
1193-
free(target_path);
1200+
target_path[result_length] = 0;
1201+
code = win32_lstat(target_path, result);
1202+
free(target_path);
1203+
}
11941204

11951205
return code;
11961206
}
@@ -1254,11 +1264,15 @@ win32_stat_w(const wchar_t* path, struct win32_stat *result)
12541264
result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
12551265
buf_size, VOLUME_NAME_DOS);
12561266

1257-
if(!result_length)
1267+
if(!result_length) {
1268+
free(target_path);
12581269
return -1;
1270+
}
12591271

1260-
if(!CloseHandle(hFile))
1272+
if(!CloseHandle(hFile)) {
1273+
free(target_path);
12611274
return -1;
1275+
}
12621276

12631277
target_path[result_length] = 0;
12641278
code = win32_lstat_w(target_path, result);

0 commit comments

Comments
 (0)