Bugs item #3277647, was opened at 2011-04-06 11:47
Message generated for change (Comment added) made by rupole
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=551954&aid=3277647&group_id=78018
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Series8217 (series8217)
Assigned to: Nobody/Anonymous (nobody)
Summary: GetOpenFileNameW may return a C-style null-terminated string
Initial Comment:
*Environment*
Windows 7 Professional 64-bit (no service pack), Python 2.7.1, PyWin32 Build 216
Addtl Note: I posted this as a question on Stack Overflow here: http://stackoverflow.com/questions/5559810/how-do-i-handle-python-unicode-strings-with-null-bytes-the-right-way/5559907
One other user has noted that the problem does not occur for them on Windows 7 SP1 64-bit with the same PyWin32 build (216) and Python 2.6.5 64-bit.
*Problem Description*
I'm using the Win32 file chooser function GetOpenFileNameW from the PyWin32 package. According to the documentation, this function returns a tuple containing the full filename path as a Python unicode object.
When I open the dialog with an existing path and filename set, I get a strange return value.
For example I had the default set to: C:\\Users\\Guest\\MyFileIsReallyReallyReallyAwesome.asy
In the dialog I changed the name to MyFile.asy and clicked save.
The full path part of the return value was: u'C:\Users\Guest\MyFile.asy\x00wesome.asy'`
I expected it to be: u'C:\\Users\\Guest\\MyFile.asy'
It appears that GetOopenFileNameW is returning a recycled buffer (from the default file path it seems) without trimming off the terminating bytes. Needless to say, the rest of my code wasn't set up for handling a C-style null-terminated string.
*Demo Code*
The following code demonstrates null-terminated string in return value from GetSaveFileNameW.
Directions: In the dialog change the filename to 'MyFile.asy' then click Save. Observe what is printed to the console. The output I get is u'C:\\Users\\Guest\\MyFile.asy\x00wesome.asy'.
import win32gui, win32con
if __name__ == "__main__":
initial_dir = 'C:\\Users\\Guest'
initial_file = 'MyFileIsReallyReallyReallyAwesome.asy'
filter_string = 'All Files\0*.*\0'
(filename, customfilter, flags) = \
win32gui.GetSaveFileNameW(InitialDir=initial_dir,
Flags=win32con.OFN_EXPLORER, File=initial_file,
DefExt='txt', Title="Save As", Filter=filter_string,
FilterIndex=0)
print repr(filename)
Note: If you don't shorten the filename enough (for example, if you try MyFileIsReally.asy) the string will be complete without a null byte.
----------------------------------------------------------------------
>Comment By: Roger Upole (rupole)
Date: 2011-04-08 20:31
Message:
This is because this function can legimately return a string with embedded
nulls when multiple files are selected. The wrapper code could be smarter
about how the string is trimmed, though. Cutting it off at a double null
might be the way to go. However, if you're only allowing a single
selection, you can just split it on '\x00' and use the first piece.
----------------------------------------------------------------------
Comment By: Series8217 (series8217)
Date: 2011-04-06 15:07
Message:
I added the test script as an attachment because the formatting is messed
up in the original bug details.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=551954&aid=3277647&group_id=78018
|