diff options
-rw-r--r-- | include/base64.h (renamed from ndb/include/util/Base64.hpp) | 41 | ||||
-rw-r--r-- | mysys/Makefile.am | 7 | ||||
-rw-r--r-- | mysys/base64.c | 265 | ||||
-rw-r--r-- | ndb/config/type_ndbapi.mk.am | 4 | ||||
-rw-r--r-- | ndb/config/type_util.mk.am | 7 | ||||
-rw-r--r-- | ndb/src/common/util/Base64.cpp | 212 | ||||
-rw-r--r-- | ndb/src/common/util/Makefile.am | 2 | ||||
-rw-r--r-- | ndb/src/common/util/Parser.cpp | 7 | ||||
-rw-r--r-- | ndb/src/mgmapi/mgmapi.cpp | 14 | ||||
-rw-r--r-- | ndb/src/mgmsrv/Services.cpp | 12 |
10 files changed, 330 insertions, 241 deletions
diff --git a/ndb/include/util/Base64.hpp b/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 <UtilBuffer.hpp> -#include <BaseString.hpp> +#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 <mysys_priv.h> + +/* + 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 <base64.h> +#include <m_string.h> // 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<src_len; j++) + { + char c= rand(); + *s++= c; + } + + /* Encode */ + char * str= (char *) malloc(base64_needed_encoded_length(src_len)); + require(base64_encode(src, src_len, str) == 0); + + /* Decode */ + char * dst= (char *) malloc(base64_needed_decoded_length(strlen(str))); + dst_len= base64_decode(str, strlen(str), dst); + require(dst_len == src_len); + + if (memcmp(src, dst, src_len) != 0) + { + printf(" --------- src --------- --------- dst ---------\n"); + for (k= 0; k<src_len; k+=8) + { + printf("%.4x ", (uint) k); + for (l=0; l<8 && k+l<src_len; l++) + { + unsigned char c= src[k+l]; + printf("%.2x ", (unsigned)c); + } + + printf(" "); + + for (l=0; l<8 && k+l<dst_len; l++) + { + unsigned char c= dst[k+l]; + printf("%.2x ", (unsigned)c); + } + printf("\n"); + } + printf("src length: %.8x, dst length: %.8x\n", + (uint) src_len, (uint) dst_len); + require(0); + } + } + printf("Test succeeded.\n"); + return 0; +} + +#endif diff --git a/ndb/config/type_ndbapi.mk.am b/ndb/config/type_ndbapi.mk.am index ed648273aea..ab84c683e86 100644 --- a/ndb/config/type_ndbapi.mk.am +++ b/ndb/config/type_ndbapi.mk.am @@ -1,6 +1,8 @@ INCLUDES += \ - -I$(srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/ndb/include \ + -I$(srcdir) -I$(top_srcdir)/include \ + -I$(top_srcdir)/mysys \ + -I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include/kernel \ -I$(top_srcdir)/ndb/include/transporter \ -I$(top_srcdir)/ndb/include/debugger \ diff --git a/ndb/config/type_util.mk.am b/ndb/config/type_util.mk.am index 0dfa77b7a7c..9e716d7cca6 100644 --- a/ndb/config/type_util.mk.am +++ b/ndb/config/type_util.mk.am @@ -1,6 +1,11 @@ -INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \ +INCLUDES += -I$(srcdir) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/mysys \ -I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include/util \ -I$(top_srcdir)/ndb/include/portlib \ -I$(top_srcdir)/ndb/include/logger + +LDADD += \ + $(top_builddir)/mysys/libmysys.a diff --git a/ndb/src/common/util/Base64.cpp b/ndb/src/common/util/Base64.cpp deleted file mode 100644 index 3db911f481f..00000000000 --- a/ndb/src/common/util/Base64.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* 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 <ndb_global.h> -#include <Base64.hpp> - -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<len; j++){ - char c = rand(); - src.append(&c, 1); - } - require(src.length() == len); - - BaseString str; - require(base64_encode(src, str) == 0); - - if(str.length() == 3850){ - printf(">%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<len; i2++){ - unsigned char c = c_src[i2]; - printf("%.2x ", (unsigned)c); - if((i2 % 8) == 7) - printf("\n"); - } - printf("\n"); - - printf("-- dst --\n"); - for(int i2 = 0; i2<len; i2++){ - unsigned char c = c_dst[i2]; - printf("%.2x ", (unsigned)c); - if((i2 % 8) == 7) - printf("\n"); - } - printf("\n"); - abort(); - } - } - return 0; -} - -#endif diff --git a/ndb/src/common/util/Makefile.am b/ndb/src/common/util/Makefile.am index 2719d14ee92..75a1d970f7a 100644 --- a/ndb/src/common/util/Makefile.am +++ b/ndb/src/common/util/Makefile.am @@ -5,7 +5,7 @@ libgeneral_la_SOURCES = \ File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \ SimpleProperties.cpp Parser.cpp InputStream.cpp \ SocketServer.cpp SocketClient.cpp SocketAuthenticator.cpp\ - OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \ + OutputStream.cpp NdbOut.cpp BaseString.cpp \ NdbSqlUtil.cpp new.cpp \ uucode.c random.c version.c \ strdup.c \ diff --git a/ndb/src/common/util/Parser.cpp b/ndb/src/common/util/Parser.cpp index d692aa18392..3a86ae8f318 100644 --- a/ndb/src/common/util/Parser.cpp +++ b/ndb/src/common/util/Parser.cpp @@ -20,7 +20,6 @@ #include "Parser.hpp" #include <NdbOut.hpp> #include <Properties.hpp> -#include <Base64.hpp> #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 <Parser.hpp> #include <OutputStream.hpp> #include <InputStream.hpp> -#include <Base64.hpp> +#include <base64.h> #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 <signaldata/SetLogLevelOrd.hpp> #include <LogLevel.hpp> #include <BaseString.hpp> -#include <Base64.hpp> #include <ConfigValues.hpp> #include <mgmapi_configuration.hpp> @@ -33,6 +32,8 @@ #include "Services.hpp" #include "../mgmapi/ndb_logevent.hpp" +#include <base64.h> + 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; } |