From 006cf01bc9c50fa500ebf1dbc562a36daf40cb84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Thu, 18 Apr 2013 20:22:30 +0200
Subject: Replacing Base64 by LibTomCrypt implementation.

Change-Id: I6c3fe2c7c8acfad9a2c811ff26e02cc952880c19

diff --git a/COPYING.thirdparty b/COPYING.thirdparty
index a82799b..1ab927d 100644
--- a/COPYING.thirdparty
+++ b/COPYING.thirdparty
@@ -757,3 +757,47 @@ necessary.  Here is a sample; alter the names:
 
 That's all there is to it!
 
+
+===========
+LibTomCrypt
+===========
+
+Swiften contains adapted code from LibTomCrypt by Tom St Denis
+LibTomCrypt is free for all purposes under the public domain.
+
+
+===
+MD5
+===
+
+Swiften contains adapted code from L. Peter Deutsch's
+MD5 implementation. Original license below.
+
+Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
+
+This software is provided 'as-is', without any express or implied
+warranty.  In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+	 claim that you wrote the original software. If you use this software
+	 in a product, an acknowledgment in the product documentation would be
+	 appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+	 misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+L. Peter Deutsch
+ghost@aladdin.com
+
+
+=====
+SHA-1
+=====
+
+Swiften contains adapted code from Steve Reid's SHA-1 implementation in C.
+This code is in the public domain.
\ No newline at end of file
diff --git a/Swiften/StringCodecs/Base64.cpp b/Swiften/StringCodecs/Base64.cpp
index 195987e..76e2833 100644
--- a/Swiften/StringCodecs/Base64.cpp
+++ b/Swiften/StringCodecs/Base64.cpp
@@ -4,6 +4,8 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
+// Code copied & adapted from LibTomCrypt by Tom St Denis
+
 #include <boost/numeric/conversion/cast.hpp>
 
 #include <algorithm>
@@ -11,120 +13,109 @@
 #include <Swiften/StringCodecs/Base64.h>
 #include <Swiften/Base/Algorithm.h>
 
-namespace Swift {
-
 #pragma GCC diagnostic ignored "-Wold-style-cast"
 #pragma clang diagnostic ignored "-Wconversion"
 
+
+static const char *codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
 namespace {
 	template<typename TargetType, typename SourceType>
-	TargetType base64Encode(const SourceType& s) {
-		int i;
-		int len = s.size();
-		char tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-		int a, b, c;
-
-		TargetType p;
-		p.resize((len+2)/3*4);
-		int at = 0;
-		for( i = 0; i < len; i += 3 ) {
-			a = ((unsigned char) (s[i]) & 3) << 4;
-			if(i + 1 < len) {
-				a += (unsigned char) (s[i + 1]) >> 4;
-				b = ((unsigned char) (s[i + 1]) & 0xF) << 2;
-				if(i + 2 < len) {
-					b += (unsigned char) (s[i + 2]) >> 6;
-					c = (unsigned char) (s[i + 2]) & 0x3F;
-				}
-				else
-					c = 64;
-			}
-			else {
-				b = c = 64;
-			}
-
-			p[at++] = tbl[(unsigned char) (s[i]) >> 2];
-			p[at++] = tbl[a];
-			p[at++] = tbl[b];
-			p[at++] = tbl[c];
-		}
-		return p;
-	}
+ 	TargetType base64Encode(const SourceType& in) {
+ 		TargetType out;
+
+ 		size_t i;
+ 		unsigned int leven = 3*(in.size() / 3);
+ 		for (i = 0; i < leven; i += 3) {
+ 			out.push_back(codes[(in[i] >> 2) & 0x3F]);
+ 			out.push_back(codes[(((in[i] & 3) << 4) + (in[i+1] >> 4)) & 0x3F]);
+ 			out.push_back(codes[(((in[i+1] & 0xf) << 2) + (in[i+2] >> 6)) & 0x3F]);
+ 			out.push_back(codes[in[i+2] & 0x3F]);
+ 		}
+ 		if (i < in.size()) {
+ 			unsigned int a = in[i];
+ 			unsigned int b = (i+1 < in.size()) ? in[i+1] : 0;
+
+ 			out.push_back(codes[(a >> 2) & 0x3F]);
+ 			out.push_back(codes[(((a & 3) << 4) + (b >> 4)) & 0x3F]);
+ 			out.push_back((i+1 < in.size()) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=');
+ 			out.push_back('=');
+ 		}
+ 		return out;
+ 	}
 }
 
-std::string Base64::encode(const ByteArray &s) {
-	return base64Encode<std::string, ByteArray>(s);
-}
+static const unsigned char map[256] = {
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
+	52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
+	255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
+	7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
+	19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,
+	255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
+	37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
+	49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255 };
 
-SafeByteArray Base64::encode(const SafeByteArray &s) {
-	return base64Encode<SafeByteArray, SafeByteArray>(s);
-}
+namespace Swift {
+	std::string Base64::encode(const ByteArray &s) {
+		return base64Encode<std::string, ByteArray>(s);
+	}
 
-ByteArray Base64::decode(const std::string& input) {
-	std::string inputWithoutNewlines(input);
-	erase(inputWithoutNewlines, '\n');
-
-	const std::string& s = inputWithoutNewlines;
-	ByteArray p;
-
-	// -1 specifies invalid
-	// 64 specifies eof
-	// everything else specifies data
-
-	char tbl[] = {
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
-		52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,
-		-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
-		15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
-		-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
-		41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-	};
-
-	// this should be a multiple of 4
-	int len = s.size();
-
-	if(len % 4) {
-		return p;
+	SafeByteArray Base64::encode(const SafeByteArray &s) {
+		return base64Encode<SafeByteArray, SafeByteArray>(s);
 	}
 
-	p.resize(len / 4 * 3);
+	ByteArray Base64::decode(const std::string& input) {
+		std::string inputWithoutNewlines(input);
+		erase(inputWithoutNewlines, '\n');
+
+		const std::string& s = inputWithoutNewlines;
+		ByteArray out;
 
-	int i;
-	int at = 0;
+		int g = 3;
+		size_t y, t;
+		for (size_t x = y = t = 0; x < s.size(); ++x) {
+			unsigned char c = map[s[x]&0xFF];
+			if (c == 255) {
+				continue;
+			}
+		 /* the final = symbols are read and used to trim the remaining bytes */
+			if (c == 254) { 
+				c = 0; 
+				/* prevent g < 0 which would potentially allow an overflow later */
+				if (--g < 0) {
+					return ByteArray();
+				}
+			} else if (g != 3) {
+				/* we only allow = to be at the end */
+				return ByteArray();
+			}
 
-	int a, b, c, d;
-	c = d = 0;
+			t = (t<<6)|c;
 
-	for( i = 0; i < len; i += 4 ) {
-		a = tbl[boost::numeric_cast<int>(s[i])];
-		b = tbl[boost::numeric_cast<int>(s[i + 1])];
-		c = tbl[boost::numeric_cast<int>(s[i + 2])];
-		d = tbl[boost::numeric_cast<int>(s[i + 3])];
-		if((a == 64 || b == 64) || (a < 0 || b < 0 || c < 0 || d < 0)) {
-			p.resize(0);
-			return p;
+			if (++y == 4) {
+				out.push_back((unsigned char)((t>>16)&255));
+				if (g > 1) out.push_back((unsigned char)((t>>8)&255));
+				if (g > 2) out.push_back((unsigned char)(t&255));
+				y = t = 0;
+			}
+		}
+		if (y != 0) {
+			return ByteArray();
 		}
-		p[at++] = ((a & 0x3F) << 2) | ((b >> 4) & 0x03);
-		p[at++] = ((b & 0x0F) << 4) | ((c >> 2) & 0x0F);
-		p[at++] = ((c & 0x03) << 6) | ((d >> 0) & 0x3F);
+		return out;
 	}
-
-	if(c & 64)
-		p.resize(at - 2);
-	else if(d & 64)
-		p.resize(at - 1);
-
-	return p;
-}
-
 }
-- 
cgit v0.10.2-6-g49f6