Question

A small detail caught my eye while reading documentation of _splitpath_s(). It takes path of a disk item (e.g.; C:\Temp\MyFile.exe) in its 1st parameter, and then splits it into drive, directory, folder and extension names. However, the strange thing is, it asks for length of the string buffer that will hold name of the drive in return in its 3rd parameter.

As far as I know, a drive letter can be nothing but a two-letter string; a letter followed by a semicolon, like A:, B:, C:, etc. Therefore, it must always be a two-character string under all cases. But if so, just why does _splitpath_s() ask for length of drive letter? Is there any case which drive letter can be in a different format? What problem would had occurred at worst, if it didn't ask for its length and just assumed it to be 2?

errno_t _splitpath_s(
   const char * path,
   char * drive,
   size_t driveNumberOfElements,
   char * dir,
   size_t dirNumberOfElements,
   char * fname,
   size_t nameNumberOfElements,
   char * ext, 
   size_t extNumberOfElements
);
Était-ce utile?

La solution

The point of the _s functions is to be paranoid about buffer overflows. All buffers therefore should be associated with a size.

Your proposal to use a two-character string would mean that either the colon would be omitted (which from a usage perspective would be annoying) or would mean that the string is not NUL-terminated, which probably is unexpected (especially since it would be inconsistent with all of the other output parameters, which are NUL-terminated) and which then could lead to other security vulnerabilities.

Even if you amended your proposal to use a fixed-size buffer of three characters instead of two, in C, declaring array parameters to functions doesn't really do anything; the compiler will not enforce that an argument is an array of the correct size. That is, a function like:

 void foo(int array[3]);

is not actually any different from:

 void foo(int* array);

If _splitpath_s did not take a driveNumberOfElements parameter, it would be easier for callers to accidentally pass buffers that are too small. While it's true that callers can still do that in its current form, the presence of the explicit driveNumberOfElements parameter should make callers pay some attention to this.

Finally, in theory, drives someday might not be restricted to single characters, so a version of _splitpath_s that takes a driveNumberOfElements parameter is a bit more future-proof. (In practice, however, such a change would break lots of existing code.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top