From 2a49fa62a0b963ea084b0720039c2420c2cec91b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Oct 2005 01:14:23 +0200 Subject: [PATCH 1/2] WL#2835: Base64 mysys functions mysys/Makefile.am: Added Base64 to mysys ndb/config/type_ndbapi.mk.am: NDBAPI now dependent on mysys ndb/config/type_util.mk.am: NDB UTIL now dependent on mysys ndb/src/common/util/Makefile.am: Remove Base64 ndb/src/common/util/Parser.cpp: Removed dead code ndb/src/mgmapi/mgmapi.cpp: Use of mysys Base64 ndb/src/mgmsrv/Services.cpp: Use of mysys Base64 include/base64.h: Making Base64 mysys-style mysys/base64.c: Making Base64 mysys-compatible --- .../util/Base64.hpp => include/base64.h | 41 ++- mysys/Makefile.am | 7 +- mysys/base64.c | 265 ++++++++++++++++++ ndb/config/type_ndbapi.mk.am | 4 +- ndb/config/type_util.mk.am | 7 +- ndb/src/common/util/Base64.cpp | 212 -------------- ndb/src/common/util/Makefile.am | 2 +- ndb/src/common/util/Parser.cpp | 7 +- ndb/src/mgmapi/mgmapi.cpp | 14 +- ndb/src/mgmsrv/Services.cpp | 12 +- 10 files changed, 330 insertions(+), 241 deletions(-) rename ndb/include/util/Base64.hpp => include/base64.h (53%) create mode 100644 mysys/base64.c delete mode 100644 ndb/src/common/util/Base64.cpp diff --git a/ndb/include/util/Base64.hpp b/include/base64.h similarity index 53% rename from ndb/include/util/Base64.hpp rename to include/base64.h index f4b11ad9214..fcc2f8b40dc 100644 --- a/ndb/include/util/Base64.hpp +++ b/include/base64.h @@ -14,15 +14,38 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __BASE64_HPP_INCLUDED__ -#define __BASE64_HPP_INCLUDED__ +#ifndef __BASE64_H_INCLUDED__ +#define __BASE64_H_INCLUDED__ -#include -#include +#ifdef __cplusplus +extern "C" { +#endif -int base64_encode(const UtilBuffer &src, BaseString &dst); -int base64_encode(const void * s, size_t src_len, BaseString &dst); -int base64_decode(const BaseString &src, UtilBuffer &dst); -int base64_decode(const char * s, size_t len, UtilBuffer &dst); -#endif /* !__BASE64_HPP_INCLUDED__ */ +#include + +/* + Calculate how much memory needed for dst of base64_encode() +*/ +int base64_needed_encoded_length(int length_of_data); + +/* + Calculate how much memory needed for dst of base64_decode() +*/ +int base64_needed_decoded_length(int length_of_encoded_data); + +/* + Encode data as a base64 string +*/ +int base64_encode(const void *src, size_t src_len, char *dst); + +/* + Decode a base64 string into data +*/ +int base64_decode(const char *src, size_t src_len, void *dst); + + +#ifdef __cplusplus +} +#endif +#endif /* !__BASE64_H_INCLUDED__ */ diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 9c58c18cf59..ee0dcb544b6 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -55,7 +55,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ charset.c charset-def.c my_bitmap.c my_bit.c md5.c \ my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_handler.c my_netware.c my_largepage.c \ - my_windac.c my_access.c + my_windac.c my_access.c base64.c EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c libmysys_a_LIBADD = @THREAD_LOBJECTS@ @@ -116,5 +116,10 @@ test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LIBRARIES) $(LINK) $(FLAGS) -DMAIN ./test_gethwaddr.c $(LDADD) $(LIBS) $(RM) -f ./test_gethwaddr.c +test_base64$(EXEEXT): base64.c $(LIBRARIES) + $(CP) $(srcdir)/base64.c ./test_base64.c + $(LINK) $(FLAGS) -DMAIN ./test_base64.c $(LDADD) $(LIBS) + $(RM) -f ./test_base64.c + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/mysys/base64.c b/mysys/base64.c new file mode 100644 index 00000000000..d4ddf333c84 --- /dev/null +++ b/mysys/base64.c @@ -0,0 +1,265 @@ +/* Copyright (C) 2003 MySQL AB + + 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include // strchr() + +#ifndef MAIN + +static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + +int +base64_needed_encoded_length(int length_of_data) +{ + return ceil(length_of_data * 4 / 3) /* base64 chars */ + + ceil(length_of_data / (76 * 3 / 4)) /* Newlines */ + + 3 /* Padding */; +} + + +int +base64_needed_decoded_length(int length_of_encoded_data) +{ + return ceil(length_of_encoded_data * 3 / 4); +} + + +/* + Encode a data as base64. + + Note: We require that dst is pre-allocated to correct size. + See base64_needed_encoded_length(). +*/ + +int +base64_encode(const void *src, size_t src_len, char *dst) +{ + const unsigned char *s= (const unsigned char*)src; + size_t i= 0; + size_t len= 0; + + for (; i < src_len; len += 4) + { + if (len == 76) + { + len= 0; + *dst++= '\n'; + } + + unsigned c; + c= s[i++]; + c <<= 8; + + if (i < src_len) + c += s[i]; + c <<= 8; + i++; + + if (i < src_len) + c += s[i]; + i++; + + *dst++= base64_table[(c >> 18) & 0x3f]; + *dst++= base64_table[(c >> 12) & 0x3f]; + + if (i > (src_len + 1)) + *dst++= '='; + else + *dst++= base64_table[(c >> 6) & 0x3f]; + + if (i > src_len) + *dst++= '='; + else + *dst++= base64_table[(c >> 0) & 0x3f]; + } + + return 0; +} + + +static inline unsigned +pos(unsigned char c) +{ + return strchr(base64_table, c) - base64_table; +} + + +#define SKIP_SPACE(src, i, size) \ +{ \ + while (i < size && my_isspace(default_charset_info, * src)) \ + { \ + i++; \ + src++; \ + } \ + if (i == size) \ + { \ + i= size + 1; \ + break; \ + } \ +} + + +/* + Decode a base64 string + + Note: We require that dst is pre-allocated to correct size. + See base64_needed_decoded_length(). + + RETURN Number of bytes produced in dst or -1 in case of failure +*/ +int +base64_decode(const char *src, size_t size, void *dst) +{ + char b[3]; + size_t i= 0; + void *d= dst; + size_t j; + + while (i < size) + { + unsigned c= 0; + size_t mark= 0; + + SKIP_SPACE(src, i, size); + + c += pos(*src++); + c <<= 6; + i++; + + SKIP_SPACE(src, i, size); + + c += pos(*src++); + c <<= 6; + i++; + + SKIP_SPACE(src, i, size); + + if (* src != '=') + c += pos(*src++); + else + { + i= size; + mark= 2; + c <<= 6; + goto end; + } + c <<= 6; + i++; + + SKIP_SPACE(src, i, size); + + if (*src != '=') + c += pos(*src++); + else + { + i= size; + mark= 1; + goto end; + } + i++; + + end: + b[0]= (c >> 16) & 0xff; + b[1]= (c >> 8) & 0xff; + b[2]= (c >> 0) & 0xff; + + for (j=0; j<3-mark; j++) + *(char *)d++= b[j]; + } + + if (i != size) + { + return -1; + } + return d - dst; +} + + +#else /* MAIN */ + +#define require(b) { \ + if (!(b)) { \ + printf("Require failed at %s:%d\n", __FILE__, __LINE__); \ + abort(); \ + } \ +} + + +int +main(void) +{ + int i; + size_t j; + size_t k, l; + size_t dst_len; + + for (i= 0; i < 500; i++) + { + /* Create source data */ + const size_t src_len= rand() % 1000 + 1; + + char * src= (char *) malloc(src_len); + char * s= src; + + for (j= 0; j -#include - -static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - -int -base64_encode(const UtilBuffer &src, BaseString &dst) -{ - return base64_encode(src.get_data(), src.length(), dst); -} - -int -base64_encode(const void * _s, size_t src_len, BaseString &dst) { - const unsigned char * s = (const unsigned char*)_s; - size_t i = 0; - size_t len = 0; - while(i < src_len) { - if(len == 76){ - len = 0; - dst.append('\n'); - } - - unsigned c; - c = s[i++]; - c <<= 8; - - if(i < src_len) - c += s[i]; - c <<= 8; - i++; - - if(i < src_len) - c += s[i]; - i++; - - dst.append(base64_table[(c >> 18) & 0x3f]); - dst.append(base64_table[(c >> 12) & 0x3f]); - - if(i > (src_len + 1)) - dst.append('='); - else - dst.append(base64_table[(c >> 6) & 0x3f]); - - if(i > src_len) - dst.append('='); - else - dst.append(base64_table[(c >> 0) & 0x3f]); - - len += 4; - } - return 0; -} - -static inline unsigned -pos(unsigned char c) { - return strchr(base64_table, c) - base64_table; -} - - -int -base64_decode(const BaseString &src, UtilBuffer &dst) { - return base64_decode(src.c_str(), src.length(), dst); -} - -#define SKIP_SPACE(src, i, size){ \ - while(i < size && isspace(* src)){ \ - i++; \ - src++; \ - } \ - if(i == size){ \ - i = size + 1; \ - break; \ - } \ -} - -int -base64_decode(const char * src, size_t size, UtilBuffer &dst) { - size_t i = 0; - while(i < size){ - unsigned c = 0; - int mark = 0; - - SKIP_SPACE(src, i, size); - - c += pos(*src++); - c <<= 6; - i++; - - SKIP_SPACE(src, i, size); - - c += pos(*src++); - c <<= 6; - i++; - - SKIP_SPACE(src, i, size); - - if(* src != '=') - c += pos(*src++); - else { - i = size; - mark = 2; - c <<= 6; - goto end; - } - c <<= 6; - i++; - - SKIP_SPACE(src, i, size); - - if(*src != '=') - c += pos(*src++); - else { - i = size; - mark = 1; - goto end; - } - i++; - - end: - char b[3]; - b[0] = (c >> 16) & 0xff; - b[1] = (c >> 8) & 0xff; - b[2] = (c >> 0) & 0xff; - - dst.append((void *)b, 3-mark); - } - - if(i != size){ - abort(); - return -1; - } - return 0; -} - -#ifdef __TEST__B64 -/** - * USER_FLAGS="-D__TEST__B64" make Base64.o && g++ Base64.o BaseString.o - */ -inline -void -require(bool b){ - if(!b) - abort(); -} - -int -main(void){ - for(int i = 0; i < 500; i++){ - const size_t len = rand() % 10000 + 1; - UtilBuffer src; - for(size_t j = 0; j%s<\n", str.c_str()); - } - - UtilBuffer dst; - require(base64_decode(str, dst) == 0); - require(dst.length() == src.length()); - - const char * c_src = (char*)src.get_data(); - const char * c_dst = (char*)dst.get_data(); - if(memcmp(src.get_data(), dst.get_data(), src.length()) != 0){ - printf("-- src --\n"); - for(int i2 = 0; i2 #include -#include #undef DEBUG #define DEBUG(x) ndbout << x << endl; @@ -316,11 +315,7 @@ ParserImpl::parseArg(Context * ctx, } case DummyRow::Properties: { - Properties *sp = new Properties(); - BaseString v(value); - UtilBuffer b; - base64_decode(v, b); - sp->unpack((const Uint32 *)b.get_data(), b.length()); + abort(); break; } default: diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 8263e8cbc93..df27b1b358a 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -34,8 +34,8 @@ #include #include #include -#include +#include #define MGM_CMD(name, fun, desc) \ { name, \ @@ -1770,11 +1770,15 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { } while(start < len); if(buf64 == 0) break; - + + void *tmp_data = malloc(base64_needed_decoded_length((size_t) (len - 1))); + const int res = base64_decode(buf64, len-1, tmp_data); + delete[] buf64; UtilBuffer tmp; - const int res = base64_decode(buf64, len-1, tmp); - delete[] buf64; - if(res != 0){ + tmp.append((void *) tmp_data, res); + free(tmp_data); + if (res < 0) + { fprintf(handle->errstream, "Failed to decode buffer\n"); break; } diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index ed32ab9c963..9a4980eefdc 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -33,6 +32,8 @@ #include "Services.hpp" #include "../mgmapi/ndb_logevent.hpp" +#include + extern bool g_StopServer; static const unsigned int MAX_READ_TIMEOUT = 1000 ; @@ -598,17 +599,18 @@ MgmApiSession::getConfig_common(Parser_t::Context &, cfg->pack(src); NdbMutex_Unlock(m_mgmsrv.m_configMutex); - BaseString str; - int res = base64_encode(src, str); + char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length())); + int res = base64_encode(src.get_data(), src.length(), tmp_str); m_output->println("get config reply"); m_output->println("result: Ok"); - m_output->println("Content-Length: %d", str.length()); + m_output->println("Content-Length: %d", strlen(tmp_str)); m_output->println("Content-Type: ndbconfig/octet-stream"); m_output->println("Content-Transfer-Encoding: base64"); m_output->println(""); - m_output->println(str.c_str()); + m_output->println(tmp_str); + free(tmp_str); return; } From fed8930184614ea1539d684f330b4a3d92c47011 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Oct 2005 16:18:08 +0200 Subject: [PATCH 2/2] WL#2835: Base64 Fixes after Jonas review mysys/base64.c: Changed charset by recommendation of bar ndb/config/type_util.mk.am: Removed redundant library --- mysys/base64.c | 2 +- ndb/config/type_util.mk.am | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/mysys/base64.c b/mysys/base64.c index d4ddf333c84..7dcca6f14ac 100644 --- a/mysys/base64.c +++ b/mysys/base64.c @@ -102,7 +102,7 @@ pos(unsigned char c) #define SKIP_SPACE(src, i, size) \ { \ - while (i < size && my_isspace(default_charset_info, * src)) \ + while (i < size && my_isspace(&my_charset_latin1, * src)) \ { \ i++; \ src++; \ diff --git a/ndb/config/type_util.mk.am b/ndb/config/type_util.mk.am index 9e716d7cca6..4f2d605dc91 100644 --- a/ndb/config/type_util.mk.am +++ b/ndb/config/type_util.mk.am @@ -6,6 +6,3 @@ INCLUDES += -I$(srcdir) \ -I$(top_srcdir)/ndb/include/util \ -I$(top_srcdir)/ndb/include/portlib \ -I$(top_srcdir)/ndb/include/logger - -LDADD += \ - $(top_builddir)/mysys/libmysys.a