From bc743ca7ced997e75ee72b8f493f6ffb14879aad Mon Sep 17 00:00:00 2001
From: Perttu Ahola <celeron55@gmail.com>
Date: Wed, 4 Jan 2012 00:37:46 +0200
Subject: Add missing checks to texture caching

---
 src/client.cpp     | 17 +++++++++++++++--
 src/clientserver.h |  2 ++
 src/server.cpp     | 18 +++++++++++++++++-
 3 files changed, 34 insertions(+), 3 deletions(-)

(limited to 'src')

diff --git a/src/client.cpp b/src/client.cpp
index aca38b166..38ed14978 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -1276,6 +1276,13 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
 			//read texture from cache
 			std::string name = deSerializeString(is);
 			std::string sha1_texture = deSerializeString(is);
+			
+			// if name contains illegal characters, ignore the texture
+			if(!string_allowed(name, TEXTURENAME_ALLOWED_CHARS)){
+				errorstream<<"Client: ignoring illegal texture name "
+						<<"sent by server: \""<<name<<"\""<<std::endl;
+				continue;
+			}
 
 			std::string tpath = getTextureCacheDir() + DIR_DELIM + name;
 			// Read data
@@ -1371,8 +1378,6 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
 				for each texture {
 					u16 length of name
 					string name
-					u16 length of path
-					string path
 				}
 		 */
 		std::ostringstream os(std::ios_base::binary);
@@ -1439,6 +1444,14 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
 		for(int i=0; i<num_textures; i++){
 			std::string name = deSerializeString(is);
 			std::string data = deSerializeLongString(is);
+
+			// if name contains illegal characters, ignore the texture
+			if(!string_allowed(name, TEXTURENAME_ALLOWED_CHARS)){
+				errorstream<<"Client: ignoring illegal texture name "
+						<<"sent by server: \""<<name<<"\""<<std::endl;
+				continue;
+			}
+
 			// Silly irrlicht's const-incorrectness
 			Buffer<char> data_rw(data.c_str(), data.size());
 			// Create an irrlicht memory file
diff --git a/src/clientserver.h b/src/clientserver.h
index 3f97d3732..43de689e4 100644
--- a/src/clientserver.h
+++ b/src/clientserver.h
@@ -48,6 +48,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define PASSWORD_SIZE 28       // Maximum password length. Allows for
                                // base64-encoded SHA-1 (27+\0).
 
+#define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_."
+
 enum ToClientCommand
 {
 	TOCLIENT_INIT = 0x10,
diff --git a/src/server.cpp b/src/server.cpp
index 8bf9eee38..d1a71bdbc 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -4273,6 +4273,12 @@ void Server::PrepareTextures() {
 				if(dirlist[j].dir) // Ignode dirs
 					continue;
 				std::string tname = dirlist[j].name;
+				// if name contains illegal characters, ignore the texture
+				if(!string_allowed(tname, TEXTURENAME_ALLOWED_CHARS)){
+					errorstream<<"Server: ignoring illegal texture name: \""
+							<<tname<<"\""<<std::endl;
+					continue;
+				}
 				std::string tpath = texturepath + DIR_DELIM + tname;
 				// Read data
 				std::ifstream fis(tpath.c_str(), std::ios_base::binary);
@@ -4300,6 +4306,11 @@ void Server::PrepareTextures() {
 							<<tname<<"\""<<std::endl;
 					continue;
 				}
+				if(tmp_os.str().length() == 0){
+					errorstream<<"Server::PrepareTextures(): Empty file \""
+							<<tpath<<"\""<<std::endl;
+					continue;
+				}
 
 				SHA1 sha1;
 				sha1.addBytes(tmp_os.str().c_str(), tmp_os.str().length());
@@ -4332,7 +4343,7 @@ struct SendableTextureAnnouncement
 void Server::SendTextureAnnouncement(u16 peer_id){
 	DSTACK(__FUNCTION_NAME);
 
-	infostream<<"Server::SendTextureAnnouncement(): Calculate sha1 sums of textures and send to client"<<std::endl;
+	infostream<<"Server::SendTextureAnnouncement()"<<std::endl;
 
 	core::list<SendableTextureAnnouncement> texture_announcements;
 
@@ -4407,6 +4418,11 @@ void Server::SendTexturesRequested(u16 peer_id,core::list<TextureRequest> tosend
 	u32 texture_size_bunch_total = 0;
 
 	for(core::list<TextureRequest>::Iterator i = tosend.begin(); i != tosend.end(); i++) {
+		if(m_Textures.find(i->name) == m_Textures.end()){
+			errorstream<<"Server::SendTexturesRequested(): Client asked for "
+					<<"unknown texture \""<<(i->name)<<"\""<<std::endl;
+			continue;
+		}
 
 		//TODO get path + name
 		std::string tpath = m_Textures[(*i).name].path;
-- 
cgit v1.2.3