From 53391baea0d9b2fc797a6f710a54a7246375e4aa Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Fri, 17 Dec 2010 11:31:49 -0500 Subject: [PATCH] Switch out base64 decoders. Also memset the destination string so that there's no garbage data in the result. --- MacGDBp.xcodeproj/project.pbxproj | 34 ++- Source/NSXMLElementAdditions.m | 26 +- Source/base64.c | 423 ------------------------------ Source/base64.h | 45 ---- 4 files changed, 41 insertions(+), 487 deletions(-) delete mode 100644 Source/base64.c delete mode 100644 Source/base64.h diff --git a/MacGDBp.xcodeproj/project.pbxproj b/MacGDBp.xcodeproj/project.pbxproj index c04f4e6..f6cbd1b 100644 --- a/MacGDBp.xcodeproj/project.pbxproj +++ b/MacGDBp.xcodeproj/project.pbxproj @@ -16,7 +16,6 @@ 1E0AFBB90FC2518700C67031 /* HUDIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 1E0AFBB80FC2518700C67031 /* HUDIcon.png */; }; 1E1E53030DF9B89800D334F9 /* Breakpoints.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E1E53010DF9B89800D334F9 /* Breakpoints.xib */; }; 1E35FC760C6579CA0030F527 /* NSXMLElementAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E35FC750C6579CA0030F527 /* NSXMLElementAdditions.m */; }; - 1E35FEA10C6599040030F527 /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E35FEA00C6599040030F527 /* base64.c */; }; 1E416FF90D36F821009A53A2 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E416FF60D36F821009A53A2 /* MainMenu.xib */; }; 1E42F1D70F53317B008412DB /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = 1E42F1D60F53317B008412DB /* dsa_pub.pem */; }; 1E4C7AF90DA401C7000A9DC7 /* BreakpointManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E4C7AF80DA401C7000A9DC7 /* BreakpointManager.m */; }; @@ -34,6 +33,10 @@ 1EB7BED50ECF3CA90033283A /* StackFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EB7BED40ECF3CA90033283A /* StackFrame.m */; }; 1EBF4D5D0EE35F0700B62769 /* StackController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EBF4D5C0EE35F0700B62769 /* StackController.m */; }; 1EC1337E127DBB00007946FC /* VariableNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EC1337D127DBB00007946FC /* VariableNode.m */; }; + 1EC6965712BBC6A700A8D984 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 1EC6965112BBC6A700A8D984 /* LICENSE */; }; + 1EC6965812BBC6A700A8D984 /* modp_b64.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1EC6965212BBC6A700A8D984 /* modp_b64.cc */; }; + 1EC6965912BBC6A700A8D984 /* README.bluestatic in Resources */ = {isa = PBXBuildFile; fileRef = 1EC6965512BBC6A700A8D984 /* README.bluestatic */; }; + 1EC6965A12BBC6A700A8D984 /* README.chromium in Resources */ = {isa = PBXBuildFile; fileRef = 1EC6965612BBC6A700A8D984 /* README.chromium */; }; 1EEBFBE50D34C793008F835B /* Debugger.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1EEBFBE30D34C793008F835B /* Debugger.xib */; }; 1EEBFC2B0D358EBD008F835B /* StepIn.png in Resources */ = {isa = PBXBuildFile; fileRef = 1EEBFC2A0D358EBD008F835B /* StepIn.png */; }; 1EEBFC370D358F1B008F835B /* StepOut.png in Resources */ = {isa = PBXBuildFile; fileRef = 1EEBFC360D358F1B008F835B /* StepOut.png */; }; @@ -76,8 +79,6 @@ 1E0AFBB80FC2518700C67031 /* HUDIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = HUDIcon.png; path = Icons/HUDIcon.png; sourceTree = ""; }; 1E1E53020DF9B89800D334F9 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/Breakpoints.xib; sourceTree = ""; }; 1E35FC750C6579CA0030F527 /* NSXMLElementAdditions.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = NSXMLElementAdditions.m; path = Source/NSXMLElementAdditions.m; sourceTree = ""; }; - 1E35FE9F0C6599040030F527 /* base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = base64.h; path = Source/base64.h; sourceTree = ""; }; - 1E35FEA00C6599040030F527 /* base64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = base64.c; path = Source/base64.c; sourceTree = ""; }; 1E35FFB00C65A74C0030F527 /* NSXMLElementAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSXMLElementAdditions.h; path = Source/NSXMLElementAdditions.h; sourceTree = ""; }; 1E416FF70D36F821009A53A2 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; 1E42F1D60F53317B008412DB /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dsa_pub.pem; sourceTree = ""; }; @@ -106,6 +107,12 @@ 1EBF4D5C0EE35F0700B62769 /* StackController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StackController.m; path = Source/StackController.m; sourceTree = ""; }; 1EC1337C127DBB00007946FC /* VariableNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VariableNode.h; path = Source/VariableNode.h; sourceTree = ""; }; 1EC1337D127DBB00007946FC /* VariableNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VariableNode.m; path = Source/VariableNode.m; sourceTree = ""; }; + 1EC6965112BBC6A700A8D984 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + 1EC6965212BBC6A700A8D984 /* modp_b64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = modp_b64.cc; sourceTree = ""; }; + 1EC6965312BBC6A700A8D984 /* modp_b64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = modp_b64.h; sourceTree = ""; }; + 1EC6965412BBC6A700A8D984 /* modp_b64_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = modp_b64_data.h; sourceTree = ""; }; + 1EC6965512BBC6A700A8D984 /* README.bluestatic */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.bluestatic; sourceTree = ""; }; + 1EC6965612BBC6A700A8D984 /* README.chromium */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.chromium; sourceTree = ""; }; 1EEBFBE40D34C793008F835B /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/Debugger.xib; sourceTree = ""; }; 1EEBFC2A0D358EBD008F835B /* StepIn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = StepIn.png; path = Icons/StepIn.png; sourceTree = ""; }; 1EEBFC360D358F1B008F835B /* StepOut.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = StepOut.png; path = Icons/StepOut.png; sourceTree = ""; }; @@ -270,6 +277,19 @@ name = Debugger; sourceTree = ""; }; + 1EC6965012BBC6A700A8D984 /* modp_b64 */ = { + isa = PBXGroup; + children = ( + 1EC6965112BBC6A700A8D984 /* LICENSE */, + 1EC6965212BBC6A700A8D984 /* modp_b64.cc */, + 1EC6965312BBC6A700A8D984 /* modp_b64.h */, + 1EC6965412BBC6A700A8D984 /* modp_b64_data.h */, + 1EC6965512BBC6A700A8D984 /* README.bluestatic */, + 1EC6965612BBC6A700A8D984 /* README.chromium */, + ); + path = modp_b64; + sourceTree = ""; + }; 29B97314FDCFA39411CA2CEA /* MacGDBp */ = { isa = PBXGroup; children = ( @@ -287,8 +307,7 @@ children = ( 32CA4F630368D1EE00C91783 /* MacGDBp_Prefix.pch */, 29B97316FDCFA39411CA2CEA /* main.m */, - 1E35FE9F0C6599040030F527 /* base64.h */, - 1E35FEA00C6599040030F527 /* base64.c */, + 1EC6965012BBC6A700A8D984 /* modp_b64 */, ); name = "Other Sources"; sourceTree = ""; @@ -382,6 +401,9 @@ 1E9582620E252474001A3D89 /* Preferences.xib in Resources */, 1E0AFBB90FC2518700C67031 /* HUDIcon.png in Resources */, 1E6B594C11610993001189D2 /* Log.xib in Resources */, + 1EC6965712BBC6A700A8D984 /* LICENSE in Resources */, + 1EC6965912BBC6A700A8D984 /* README.bluestatic in Resources */, + 1EC6965A12BBC6A700A8D984 /* README.chromium in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -413,7 +435,6 @@ 1E02C5710C610158006F1752 /* DebuggerProcessor.m in Sources */, 1E02C5F60C610724006F1752 /* DebuggerController.m in Sources */, 1E35FC760C6579CA0030F527 /* NSXMLElementAdditions.m in Sources */, - 1E35FEA10C6599040030F527 /* base64.c in Sources */, 1EEBFD090D3599E8008F835B /* BSSplitView.m in Sources */, 1E7188680D839F6300969277 /* BSLineNumberView.m in Sources */, 1E7188690D839F6300969277 /* BSSourceView.m in Sources */, @@ -428,6 +449,7 @@ 1E6B5947116106FE001189D2 /* LoggingController.m in Sources */, 1E0724E311B47BCC0017AD3C /* DebuggerConnection.m in Sources */, 1EC1337E127DBB00007946FC /* VariableNode.m in Sources */, + 1EC6965812BBC6A700A8D984 /* modp_b64.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source/NSXMLElementAdditions.m b/Source/NSXMLElementAdditions.m index 55c8a96..a73f18e 100644 --- a/Source/NSXMLElementAdditions.m +++ b/Source/NSXMLElementAdditions.m @@ -17,7 +17,7 @@ #import #import "AppDelegate.h" -#include "base64.h" +#include "modp_b64.h" @implementation NSXMLElement (GDBpAdditions) @@ -42,19 +42,19 @@ // The value of the node is base64 encoded. if ([[[self attributeForName:@"encoding"] stringValue] isEqualToString:@"base64"]) { - const char* str = [[self stringValue] UTF8String]; - int strlen = [[self stringValue] length]; - - char* data; - size_t datalen; - - if (!base64_decode_alloc(str, strlen, &data, &datalen)) - NSLog(@"error in converting %@ from base64", self); - + const char* src = [[self stringValue] UTF8String]; + int srclen = [[self stringValue] length]; + + int destlen = modp_b64_decode_len(srclen); + char* dest = malloc(destlen); + memset(dest, 0, destlen); + + modp_b64_decode(dest, src, srclen); + NSString* ret = nil; - if (data) { - ret = [NSString stringWithUTF8String:data]; - free(data); + if (dest) { + ret = [NSString stringWithUTF8String:dest]; + free(dest); } return ret; diff --git a/Source/base64.c b/Source/base64.c deleted file mode 100644 index 6df75d6..0000000 --- a/Source/base64.c +++ /dev/null @@ -1,423 +0,0 @@ -/* base64.c -- Encode binary data using printable characters. - Copyright (C) 1999, 2000, 2001, 2004, 2005, 2006 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Simon Josefsson. Partially adapted from GNU MailUtils - * (mailbox/filter_trans.c, as of 2004-11-28). Improved by review - * from Paul Eggert, Bruno Haible, and Stepan Kasal. - * - * See also RFC 3548 . - * - * Be careful with error checking. Here is how you would typically - * use these functions: - * - * bool ok = base64_decode_alloc (in, inlen, &out, &outlen); - * if (!ok) - * FAIL: input was not valid base64 - * if (out == NULL) - * FAIL: memory allocation error - * OK: data in OUT/OUTLEN - * - * size_t outlen = base64_encode_alloc (in, inlen, &out); - * if (out == NULL && outlen == 0 && inlen != 0) - * FAIL: input too long - * if (out == NULL) - * FAIL: memory allocation error - * OK: data in OUT/OUTLEN. - * - */ - -/* Get prototype. */ -#include "base64.h" - -/* Get malloc. */ -#include - -/* Get UCHAR_MAX. */ -#include - -/* C89 compliant way to cast 'char' to 'unsigned char'. */ -static inline unsigned char -to_uchar (char ch) -{ - return ch; -} - -/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN. - If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as - possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero - terminate the output buffer. */ -void -base64_encode (const char *restrict in, size_t inlen, - char *restrict out, size_t outlen) -{ - static const char b64str[64] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - while (inlen && outlen) - { - *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f]; - if (!--outlen) - break; - *out++ = b64str[((to_uchar (in[0]) << 4) - + (--inlen ? to_uchar (in[1]) >> 4 : 0)) - & 0x3f]; - if (!--outlen) - break; - *out++ = - (inlen - ? b64str[((to_uchar (in[1]) << 2) - + (--inlen ? to_uchar (in[2]) >> 6 : 0)) - & 0x3f] - : '='); - if (!--outlen) - break; - *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '='; - if (!--outlen) - break; - if (inlen) - inlen--; - if (inlen) - in += 3; - } - - if (outlen) - *out = '\0'; -} - -/* Allocate a buffer and store zero terminated base64 encoded data - from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e., - the length of the encoded data, excluding the terminating zero. On - return, the OUT variable will hold a pointer to newly allocated - memory that must be deallocated by the caller. If output string - length would overflow, 0 is returned and OUT is set to NULL. If - memory allocation failed, OUT is set to NULL, and the return value - indicates length of the requested memory block, i.e., - BASE64_LENGTH(inlen) + 1. */ -size_t -base64_encode_alloc (const char *in, size_t inlen, char **out) -{ - size_t outlen = 1 + BASE64_LENGTH (inlen); - - /* Check for overflow in outlen computation. - * - * If there is no overflow, outlen >= inlen. - * - * If the operation (inlen + 2) overflows then it yields at most +1, so - * outlen is 0. - * - * If the multiplication overflows, we lose at least half of the - * correct value, so the result is < ((inlen + 2) / 3) * 2, which is - * less than (inlen + 2) * 0.66667, which is less than inlen as soon as - * (inlen > 4). - */ - if (inlen > outlen) - { - *out = NULL; - return 0; - } - - *out = malloc (outlen); - if (!*out) - return outlen; - - base64_encode (in, inlen, *out, outlen); - - return outlen - 1; -} - -/* With this approach this file works independent of the charset used - (think EBCDIC). However, it does assume that the characters in the - Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255. POSIX - 1003.1-2001 require that char and unsigned char are 8-bit - quantities, though, taking care of that problem. But this may be a - potential problem on non-POSIX C99 platforms. - - IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_" - as the formal parameter rather than "x". */ -#define B64(_) \ - ((_) == 'A' ? 0 \ - : (_) == 'B' ? 1 \ - : (_) == 'C' ? 2 \ - : (_) == 'D' ? 3 \ - : (_) == 'E' ? 4 \ - : (_) == 'F' ? 5 \ - : (_) == 'G' ? 6 \ - : (_) == 'H' ? 7 \ - : (_) == 'I' ? 8 \ - : (_) == 'J' ? 9 \ - : (_) == 'K' ? 10 \ - : (_) == 'L' ? 11 \ - : (_) == 'M' ? 12 \ - : (_) == 'N' ? 13 \ - : (_) == 'O' ? 14 \ - : (_) == 'P' ? 15 \ - : (_) == 'Q' ? 16 \ - : (_) == 'R' ? 17 \ - : (_) == 'S' ? 18 \ - : (_) == 'T' ? 19 \ - : (_) == 'U' ? 20 \ - : (_) == 'V' ? 21 \ - : (_) == 'W' ? 22 \ - : (_) == 'X' ? 23 \ - : (_) == 'Y' ? 24 \ - : (_) == 'Z' ? 25 \ - : (_) == 'a' ? 26 \ - : (_) == 'b' ? 27 \ - : (_) == 'c' ? 28 \ - : (_) == 'd' ? 29 \ - : (_) == 'e' ? 30 \ - : (_) == 'f' ? 31 \ - : (_) == 'g' ? 32 \ - : (_) == 'h' ? 33 \ - : (_) == 'i' ? 34 \ - : (_) == 'j' ? 35 \ - : (_) == 'k' ? 36 \ - : (_) == 'l' ? 37 \ - : (_) == 'm' ? 38 \ - : (_) == 'n' ? 39 \ - : (_) == 'o' ? 40 \ - : (_) == 'p' ? 41 \ - : (_) == 'q' ? 42 \ - : (_) == 'r' ? 43 \ - : (_) == 's' ? 44 \ - : (_) == 't' ? 45 \ - : (_) == 'u' ? 46 \ - : (_) == 'v' ? 47 \ - : (_) == 'w' ? 48 \ - : (_) == 'x' ? 49 \ - : (_) == 'y' ? 50 \ - : (_) == 'z' ? 51 \ - : (_) == '0' ? 52 \ - : (_) == '1' ? 53 \ - : (_) == '2' ? 54 \ - : (_) == '3' ? 55 \ - : (_) == '4' ? 56 \ - : (_) == '5' ? 57 \ - : (_) == '6' ? 58 \ - : (_) == '7' ? 59 \ - : (_) == '8' ? 60 \ - : (_) == '9' ? 61 \ - : (_) == '+' ? 62 \ - : (_) == '/' ? 63 \ - : -1) - -static const signed char b64[0x100] = { - B64 (0), B64 (1), B64 (2), B64 (3), - B64 (4), B64 (5), B64 (6), B64 (7), - B64 (8), B64 (9), B64 (10), B64 (11), - B64 (12), B64 (13), B64 (14), B64 (15), - B64 (16), B64 (17), B64 (18), B64 (19), - B64 (20), B64 (21), B64 (22), B64 (23), - B64 (24), B64 (25), B64 (26), B64 (27), - B64 (28), B64 (29), B64 (30), B64 (31), - B64 (32), B64 (33), B64 (34), B64 (35), - B64 (36), B64 (37), B64 (38), B64 (39), - B64 (40), B64 (41), B64 (42), B64 (43), - B64 (44), B64 (45), B64 (46), B64 (47), - B64 (48), B64 (49), B64 (50), B64 (51), - B64 (52), B64 (53), B64 (54), B64 (55), - B64 (56), B64 (57), B64 (58), B64 (59), - B64 (60), B64 (61), B64 (62), B64 (63), - B64 (64), B64 (65), B64 (66), B64 (67), - B64 (68), B64 (69), B64 (70), B64 (71), - B64 (72), B64 (73), B64 (74), B64 (75), - B64 (76), B64 (77), B64 (78), B64 (79), - B64 (80), B64 (81), B64 (82), B64 (83), - B64 (84), B64 (85), B64 (86), B64 (87), - B64 (88), B64 (89), B64 (90), B64 (91), - B64 (92), B64 (93), B64 (94), B64 (95), - B64 (96), B64 (97), B64 (98), B64 (99), - B64 (100), B64 (101), B64 (102), B64 (103), - B64 (104), B64 (105), B64 (106), B64 (107), - B64 (108), B64 (109), B64 (110), B64 (111), - B64 (112), B64 (113), B64 (114), B64 (115), - B64 (116), B64 (117), B64 (118), B64 (119), - B64 (120), B64 (121), B64 (122), B64 (123), - B64 (124), B64 (125), B64 (126), B64 (127), - B64 (128), B64 (129), B64 (130), B64 (131), - B64 (132), B64 (133), B64 (134), B64 (135), - B64 (136), B64 (137), B64 (138), B64 (139), - B64 (140), B64 (141), B64 (142), B64 (143), - B64 (144), B64 (145), B64 (146), B64 (147), - B64 (148), B64 (149), B64 (150), B64 (151), - B64 (152), B64 (153), B64 (154), B64 (155), - B64 (156), B64 (157), B64 (158), B64 (159), - B64 (160), B64 (161), B64 (162), B64 (163), - B64 (164), B64 (165), B64 (166), B64 (167), - B64 (168), B64 (169), B64 (170), B64 (171), - B64 (172), B64 (173), B64 (174), B64 (175), - B64 (176), B64 (177), B64 (178), B64 (179), - B64 (180), B64 (181), B64 (182), B64 (183), - B64 (184), B64 (185), B64 (186), B64 (187), - B64 (188), B64 (189), B64 (190), B64 (191), - B64 (192), B64 (193), B64 (194), B64 (195), - B64 (196), B64 (197), B64 (198), B64 (199), - B64 (200), B64 (201), B64 (202), B64 (203), - B64 (204), B64 (205), B64 (206), B64 (207), - B64 (208), B64 (209), B64 (210), B64 (211), - B64 (212), B64 (213), B64 (214), B64 (215), - B64 (216), B64 (217), B64 (218), B64 (219), - B64 (220), B64 (221), B64 (222), B64 (223), - B64 (224), B64 (225), B64 (226), B64 (227), - B64 (228), B64 (229), B64 (230), B64 (231), - B64 (232), B64 (233), B64 (234), B64 (235), - B64 (236), B64 (237), B64 (238), B64 (239), - B64 (240), B64 (241), B64 (242), B64 (243), - B64 (244), B64 (245), B64 (246), B64 (247), - B64 (248), B64 (249), B64 (250), B64 (251), - B64 (252), B64 (253), B64 (254), B64 (255) -}; - -#if UCHAR_MAX == 255 -# define uchar_in_range(c) true -#else -# define uchar_in_range(c) ((c) <= 255) -#endif - -/* Return true if CH is a character from the Base64 alphabet, and - false otherwise. Note that '=' is padding and not considered to be - part of the alphabet. */ -bool -isbase64 (char ch) -{ - return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)]; -} - -/* Decode base64 encoded input array IN of length INLEN to output - array OUT that can hold *OUTLEN bytes. Return true if decoding was - successful, i.e. if the input was valid base64 data, false - otherwise. If *OUTLEN is too small, as many bytes as possible will - be written to OUT. On return, *OUTLEN holds the length of decoded - bytes in OUT. Note that as soon as any non-alphabet characters are - encountered, decoding is stopped and false is returned. This means - that, when applicable, you must remove any line terminators that is - part of the data stream before calling this function. */ -bool -base64_decode (const char *restrict in, size_t inlen, - char *restrict out, size_t *outlen) -{ - size_t outleft = *outlen; - - while (inlen >= 2) - { - if (!isbase64 (in[0]) || !isbase64 (in[1])) - break; - - if (outleft) - { - *out++ = ((b64[to_uchar (in[0])] << 2) - | (b64[to_uchar (in[1])] >> 4)); - outleft--; - } - - if (inlen == 2) - break; - - if (in[2] == '=') - { - if (inlen != 4) - break; - - if (in[3] != '=') - break; - - } - else - { - if (!isbase64 (in[2])) - break; - - if (outleft) - { - *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0) - | (b64[to_uchar (in[2])] >> 2)); - outleft--; - } - - if (inlen == 3) - break; - - if (in[3] == '=') - { - if (inlen != 4) - break; - } - else - { - if (!isbase64 (in[3])) - break; - - if (outleft) - { - *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0) - | b64[to_uchar (in[3])]); - outleft--; - } - } - } - - in += 4; - inlen -= 4; - } - - *outlen -= outleft; - - if (inlen != 0) - return false; - - return true; -} - -/* Allocate an output buffer in *OUT, and decode the base64 encoded - data stored in IN of size INLEN to the *OUT buffer. On return, the - size of the decoded data is stored in *OUTLEN. OUTLEN may be NULL, - if the caller is not interested in the decoded length. *OUT may be - NULL to indicate an out of memory error, in which case *OUTLEN - contains the size of the memory block needed. The function returns - true on successful decoding and memory allocation errors. (Use the - *OUT and *OUTLEN parameters to differentiate between successful - decoding and memory error.) The function returns false if the - input was invalid, in which case *OUT is NULL and *OUTLEN is - undefined. */ -bool -base64_decode_alloc (const char *in, size_t inlen, char **out, - size_t *outlen) -{ - /* This may allocate a few bytes too much, depending on input, - but it's not worth the extra CPU time to compute the exact amount. - The exact amount is 3 * inlen / 4, minus 1 if the input ends - with "=" and minus another 1 if the input ends with "==". - Dividing before multiplying avoids the possibility of overflow. */ - size_t needlen = 3 * (inlen / 4) + 2; - - *out = malloc (needlen); - if (!*out) - return true; - - if (!base64_decode (in, inlen, *out, &needlen)) - { - free (*out); - *out = NULL; - return false; - } - - if (outlen) - *outlen = needlen; - - return true; -} \ No newline at end of file diff --git a/Source/base64.h b/Source/base64.h deleted file mode 100644 index 68ebe95..0000000 --- a/Source/base64.h +++ /dev/null @@ -1,45 +0,0 @@ -/* base64.h -- Encode binary data using printable characters. -Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. -Written by Simon Josefsson. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef BASE64_H -# define BASE64_H - -/* Get size_t. */ -# include - -/* Get bool. */ -# include - -/* This uses that the expression (n+(k-1))/k means the smallest -integer >= n/k, i.e., the ceiling of n/k. */ -# define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4) - -extern bool isbase64 (char ch); - -extern void base64_encode (const char *restrict in, size_t inlen, - char *restrict out, size_t outlen); - -extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out); - -extern bool base64_decode (const char *restrict in, size_t inlen, - char *restrict out, size_t *outlen); - -extern bool base64_decode_alloc (const char *in, size_t inlen, - char **out, size_t *outlen); - -#endif /* BASE64_H */ \ No newline at end of file -- 2.22.5