Page 1 of 1

Windows / Unix path replacement code

PostPosted: Fri Apr 13, 2018 3:35 am
by Baker
Code: Select all
// prototype
char *String_Edit_Replace_Char (char *s_edit, int ch_find, int ch_replace, /*optional*/ int *outcount);

// Turns c:/quake/id1 into c:\quake\id1
char * File_URL_Edit_SlashesBack_Like_Windows (char *unix_path_to_file)
   // Translate "/" to "\"
   return String_Edit_Replace_Char (unix_path_to_file, '/' /*find*/, '\\' /*replace with*/, NULL /* don't want count */);

// Turns c:\quake\id1 into c:/quake/id1
char *File_URL_Edit_SlashesForward_Like_Unix (char *windows_path_to_file)
   return String_Edit_Replace_Char (windows_path_to_file, '\\' /*find*/, '/' /*replace with*/, NULL /* don't want count */);

// Short: Replaces all instances of a character with another character
// Notes: None.
char *String_Edit_Replace_Char (char *s_edit, int ch_find, int ch_replace, /*optional*/ int *outcount)
   char *cursor;
   int n;
   int count;

   for (cursor = s_edit, count = 0, n = 0; *cursor; cursor ++, n++)
      if (*cursor == ch_find)
         int c = *cursor;
         s_edit[n] = ch_replace;
         count ++;

   if (outcount) (*outcount) = count;

   return s_edit;

Re: Windows / Unix path replacement code

PostPosted: Fri Apr 13, 2018 11:23 am
by Spike
using blackslashes as a path seperator is stupid.
there are two reasons to do it:
1) you're passing them to some dos commandline program that uses forward slashes to mean options.
2) you're using one of the windows shell functions.

the first is inherently non-portable, so should be incredibly rare.
the second is flawed - if you're calling one of those functions then you really ought to be using the utf-16 version of that function instead, which is much more complicated than just swapping a few backslashes.

here are a few other filename/path considerations:
colons - not just drive separators, these are also alternative-data-stream markers and result in completely hidden 'files'.
nul, prn, conio, lptN, etc - poking any of these will probably require the user to end-task your program. have fun with that.
filenames with leading/trailing spaces - these are all sorts of buggy in windows.
filenames with a space anywhere - zomg, escaping. more bugs!
filenames with a leading dot - these are hidden files on unix. you should probably block these.
filenames with two adjacent slashes - on some systems this is treated as /../, which is bad.
filenames with ../ in them - yeah, evil.
filenames with a leading / - boo hiss! evil!
filenames with a leading \ - even more evil.
filenames with no actual name - sigh...
foreign filenames - and the codepage nightmares that come with them.
mixed case - this can be a problem even in windows.
paks with /../ in its filenames - yup, quake2 does this. fucking vile.
zips are either utf-8 or ibm437

so yeah, fte uses winapi+utf-16 to access files in windows. otherwise it assumes fopen supports utf-8, because there's no other sane way to handle it all. maps, configs, gamecode, etc is all assumed to be utf-8 when it comes to filenames. unfortunately the console doesn't necessarily agree (unless com_parseutf8 1), but that's just display and those glyphs are frequently not available anyway.
q2 does evil things with its pak files, so that stuff all gets cleaned up in fte, even for q1 (file formats are the same).
q3 mixes forward slashes and backslashes, as such fte's filesystem has to treat them as equivalent, especially on linux.

when it comes to model/sound precaches, the names are visible over a network. if the mod is inconsistent then the mod is buggy shite and the qc compiler should already be warning about models not having been precached or whatever. if the map is specifying filenames, then the qc should be using that exact string too, so a mod that bugs out on that would have to be a little bit special...

my point is that if you're going to fix up what paths mappers use, then you're forgetting ALL the other users of the engine, and its those other users that are more likely to fuck up here.
ericw's qbsp already warns about weird backslashes, so I really have no idea why your concern on func_msgboard is about maps.
regarding qc - writing qc that uses backslashes in filenames requires explicit escaping, in ANY qcc, hence why so few mods have ended up using backslashes over the years.
In other words, fix up your filesystem code instead. Its the stupid end-users that are likely to paste in the dodgy paths, or malicious servers that'll use dodgy paths to screw over clients.

Re: Windows / Unix path replacement code

PostPosted: Sat Apr 14, 2018 12:00 am
by Baker
Protecting users from themselves usually is the road to hell paved with good intentions.

That the road never ends. Some of the solutions will create new problems.

While reviewing Quakespasm's game controller code from a diff link ericw gave me, I saw a comment on the Quakespasm page on SourceForge that was reported as a bug, so that is how that post started and why the focus was mapping.