[Scummvm-devel] PORTERS: Fixing an old flaw in various FSNode implementations

Max Horn max at quendi.de
Wed Sep 3 16:46:14 CEST 2008


Hi everybody, especially you porters,

with this email (part of a series) I want to inform you about some  
changes related to the FSNode code, the class File, and in general how  
we handle files. I will try to describe briefly what changed, why, and  
how we suggest you deal with it.  As always, questions, suggestions,  
wishlists and constructive criticism are welcome :).


BACKGROUND:

There is a nasty flaw in several of our FSNode implementations, which  
all go back to the same nasty bug in the POSIX FS code (i.e. my fault,  
as usual *g*). Namely, we did not try anything to normalize paths in  
there, and used a very sloppy lastPathComponent() implementation.

Why is this bad? Well, for one thing, it makes it difficult if not  
impossible to compare nodes. If I create a node once for  "/foo/bar"  
and once for "/foo/bar/", then client code can compare those notes and  
find that they are not equal, which is maybe not waht is expected.  
Also, with the old code, displayName() would return "bar" resp.  
"bar/". Not to mention paths like
    /foo///bar/./qux///
or
    C:\\My Driver\\Files\\\

So, what FSNodes really should do is to normalize the paths (at least  
in basic ways), and also use robust code to extract the last  
component / extract the path of the "parent" node. This affects most  
node constructors, as well as the getChild() and getParent() methods.

To fix this in the POSIX FSNode class, I added two new generic funcs  
to common/str.h, including Doxygen comments:
   Common::String lastPathComponent(const Common::String &path, const  
char sep);
   Common::String normalizePath(const Common::String &path, const char  
sep);
which all ports are welcome to use.

The advantage of all this: No more worrying about adding/removing  
trailing (back)slashes from paths. Normalized paths don't have a  
trailing (back)slash, period.



PORTERS TASK: Review your FSNode code for robustness. In particular,  
double-check your constructors and the getChild() and getParent()  
methods. Do they normalize paths, are they prepared to correctly  
extract the last path component / parent dir even for "ugly" paths? I  
recommend looking at the code in backends/fs/posix/posix-fs.* as  
reference (and if you think you find bugs in there, please report  
them). Also, you may want to use Common::normalizePath &  
Common::lastPathComponent, which hopefully are sufficiently generic  
for most ports.

AFFECTED PORTS:
  Essentially *all* except the POSIX one (which has already been  
fixed), i.e.: DC, Windows, Wii, Symbian, PSP,
  Not quite sure about PS2 and Amiga, but those definitely could  
benefit from some cleanup (I am happy to share my thoughts on this  
with the respective porters, just ping me).

WARNING: Make sure to use Common::lastPathComponent and *not*  
AbstractFilesystemNode::lastPathComponent, which I recently added as  
part of a refactoring process. That method will be removed as quick as  
possible.



Cheers,
Max





More information about the Scummvm-devel mailing list