We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2435 - Windows implementation of GetBasePath is incorrect/unportable (wrong usage of GetModuleFileName)
Summary: Windows implementation of GetBasePath is incorrect/unportable (wrong usage of...
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: file (show other bugs)
Version: 2.0.1
Hardware: All Windows (All)
: P2 minor
Assignee: Ryan C. Gordon
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-07 09:47 UTC by Coriiander
Modified: 2015-05-28 19:07 UTC (History)
0 users

See Also:


Attachments
Proposed fix. (2.63 KB, patch)
2015-05-28 05:56 UTC, Ryan C. Gordon
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Coriiander 2014-03-07 09:47:55 UTC
This bug report is about the Windows-implementation of the GetBasePath-function which can be found in "src/filesystem/windows/SDL_sysfilesystem.c". The implementation is incorrect and non-portable, mainly due to a wrong usage (and linkage) of the GetModuleFileName-function (Win32 API). Another issue, albeit less important, is the hardcoded limit to the path's length which could very well exceed MAX_PATH. Eventhough I strongly discourage anyone from using this function, I have flagged the bug severity as "minor" as the GetBasePath-function isn't being used by SDL internally - it is however exported and declared in the public API headers.

As stated by MSDN (link: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683198(v=vs.85).aspx):

[----------[ BEGIN_QUOTE ]----------]
Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI version number affects the name used to call the function and the library that a program must load. If PSAPI_VERSION is 2 or greater, this function is defined as K32GetModuleFileNameEx in Psapi.h and exported in Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetModuleFileNameEx in Psapi.h and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetModuleFileNameEx.
**********
Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function as GetModuleFileNameEx. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. K32GetModuleFileNameEx.
********** 
[----------[ END_QUOTE ]----------]

Then about the hardcoded limit to the path's length. While I expect the big majority of the users running their application from a path that fits within MAX_PATH chars, the path length could very well exceed MAX_PATH. Now there are various approaches to returning a correct path. One such approach could be to call GetModuleFileNameEx in a loop, with every iteration increasing the nSize-value and increasing the size of the receiving buffer, until the returned nSize-value no longer increases.
Comment 1 Coriiander 2014-03-07 10:05:03 UTC
I forgot to add the following:

Also keep in mind that GetModuleFileName(Ex) has some varying issues between 32/64-bit/WOW64. Also its result is different with regards to the null-terminator character on Windows XP. Also the output is not necessarily a full path, but could be a short-filename, or subject to path aliassing. I expect the goal of such function is to provide the user with a useable, reliable full path, therefor I suggest to ensure to return a useable, reliable, full absolute path, in such a way that it is portable between Windows-versions. Unfortunately this is quite some work for a little, though much welcome feature, but as it is now, you should just return NULL or remove it from the public API.
Comment 2 Sam Lantinga 2014-03-08 04:55:12 UTC
Hey Ryan, how critical is this?
Comment 3 Ryan C. Gordon 2014-03-08 23:11:26 UTC
(In reply to Sam Lantinga from comment #2)
> Hey Ryan, how critical is this?

Worth fixing for 2.0.3, but not a showstopper.

--ryan.
Comment 4 Ryan C. Gordon 2015-02-19 05:22:16 UTC
Marking a large number of bugs with the "triage-2.0.4" keyword at once. Sorry if you got a lot of email from this. This is to help me sort through some bugs in regards to a 2.0.4 release. We may or may not fix this bug for 2.0.4, though!
Comment 5 Ryan C. Gordon 2015-04-07 04:57:57 UTC
(sorry if you get a lot of copies of this email, I'm marking several bugs at once)

Marking bugs for the (mostly) final 2.0.4 TODO list. This means we're hoping to resolve this bug before 2.0.4 ships if possible. In a perfect world, the open bug count with the target-2.0.4 keyword is zero when we ship.

(Note that closing a bug report as WONTFIX, INVALID or WORKSFORME might still happen.)

--ryan.
Comment 6 Ryan C. Gordon 2015-05-28 05:56:47 UTC
Created attachment 2164 [details]
Proposed fix.


Here's a patch that _should_ fix these concerns. I'm posting this to Bugzilla because I don't have a Windows machine handy to test it right now.

--ryan.
Comment 7 Sam Lantinga 2015-05-28 19:07:53 UTC
Fixed, and committed:
https://hg.libsdl.org/SDL/rev/0e1f57b051f4
https://hg.libsdl.org/SDL/rev/bc1ba207ff16