Page 1 of 1

linux bug with make_lower()

Posted: Wed Dec 26, 2007 6:34 pm
by digfarenough
I think I've reported this before, but it isn't fixed in the 1.4 release (I think I reported it for the 1.4 beta).

Filenames are case sensitive in Linux (and in OSX, I think). For some reason, Irrlicht calls make_lower() on filenames pretty often (just grep for it: it happens in CGUIEnvironment.cpp, CMeshCache.cpp, CPakReader,cpp, CQ3LevelMesh.cpp, CSceneManager.cpp, and CZipReader.cpp).

This means that if you have a file in ~/Media/font.bmp, if you try to load it as a font, Irrlicht calls make_lower() on the filename and tries to open "~/media/font.bmp"

I've no idea why Irrlicht does this, but it ought to be fixed. I just comment out the make_lower lines and recompile, but there's no reason I can think of to not just fix this in the SVN.

Posted: Wed Dec 26, 2007 11:47 pm
by hybrid
As an easy fix simply make all your files lower case. That will fix all problems on all systems. And the make_lower is not called on every path or filename, but only when storing the names into the objects. This helps to avoid redundant copies in case someone uses an uppercase or lowercase variant for the same file. Simply assume for now that Irrlicht ignores the case. If the OS does not do it you should help there as mentioned.
Are there any actual problems which cannot be fixed by renaming?

Posted: Thu Dec 27, 2007 6:13 am
by Dorth
Actually... yeah...
Any user file name, any user made mod could incorporate uppercase. Should, you could tell them to limit to lower case too, but that's kind of viral. + it force a choice on the users. I'm sure there must be an alternative.

Posted: Thu Dec 27, 2007 10:43 am
by bitplane
It would make sense to only do make_lower if the filesystem or archive is case insensitive, however, there's no way to tell at the moment.
Perhaps getting the filename of a IRead/WriteFile should do the conversion, depending on where the file lives.

Posted: Thu Dec 27, 2007 4:22 pm
by CuteAlien
I remember that I also found this some time ago and was slightly irritated. I think trying to prevent the user from doing something he *might* just accidentally do is no good idea until you explicitly mention this everywhere when files are used, as it overrides the system behavior to which programmers are used. And as digfarenough mentioned above it leads to real bugs on Linux which you only find after debugging through the irrlicht code.

I found this on serialization. In my tests for gui serialization I just loaded files and saved them again. Afterwards I checked if everything is still the same. And this modified the filenames of my imagefiles. And while I could maybe rename them, it's not the solution I'd prefer (I didn't create the files/names and so I'm reluctant to change 'em). Can't you just remove the make_lower? It feels somewhat wrong to me.

edit: I just did see that the example above seems to have a problem with the pathname. I don't have those under my control as I have to build absolute pathnames for my files so my app will still run when called like "./Path/myApp". And I have no control on which filepathes the user does use to install my games.
I thought it only happens on filenames, if paths are changed I can simply no longer use this the way it is.

Posted: Thu Dec 27, 2007 4:51 pm
by CuteAlien
A solution to this could be to stop using the filename as identifier. Use it to create an identifier and save that additionally to the filename. Whenever you work with textures internally you use the identifier. Whenever the user requests a texture by filename you convert the filename to the identifier, but you never use the identifier for file-access.

Posted: Fri Jan 18, 2008 9:34 am
by CuteAlien
I just fixed that in my own version and found another make_lower in ITexture.h which also needs to be removed. The one in the zip-reader can probably stay as it's checked by a parameter called 'IgnoreCase'.

Posted: Sun Mar 30, 2008 8:55 am
by pc0de
+1 on removing Name.make_lower() in the ITexture constructor in ITexture.h

Code: Select all

	//! constructor
	ITexture(const c8* name) : Name(name)
	{
		Name.make_lower();
	}
From what I can tell, this is the only place the original image file name is stored when loading a mesh with textures. Therefore it causes problems when converting from one mesh format to another.