From f42338922df03bdf16894ca2d43099f4a0dba1fd Mon Sep 17 00:00:00 2001 From: Cédric Ricard Date: Mon, 5 Jan 2009 11:32:27 +0000 Subject: [PATCH] - Fix extension library handling. - Working 1st extension for Anubis : base64 streamed (still in beta phase) --- anubis_dev/compiler/src/main.cpp | 4 ++-- anubis_dev/extensions/cipher/base64.cpp | 23 ++++++++++++----------- anubis_dev/extensions/cipher/base64.h | 8 ++++---- anubis_dev/library/cipher/base64.anubis | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ anubis_dev/library/predefined.anubis | 3 ++- anubis_dev/library/test/Anubis UnitTest.aproj | 1 + anubis_dev/library/test/Anubis UnitTest.ide | 8 +++++++- anubis_dev/library/test/all_unit_test.anubis | 2 ++ anubis_dev/library/test/predefined/ByteArray.ut.anubis | 28 ++++++++++++++++++++++++++++ anubis_dev/vm/src/Library.cpp | 2 +- anubis_dev/vm/src/syscall.cpp | 28 ++++++++++++++++++++-------- 11 files changed, 181 insertions(+), 28 deletions(-) create mode 100644 anubis_dev/library/cipher/base64.anubis create mode 100644 anubis_dev/library/test/predefined/ByteArray.ut.anubis diff --git a/anubis_dev/compiler/src/main.cpp b/anubis_dev/compiler/src/main.cpp index d8cf026..4ad0a92 100644 --- a/anubis_dev/compiler/src/main.cpp +++ b/anubis_dev/compiler/src/main.cpp @@ -605,9 +605,9 @@ void read_configuration_file() /* main function (Anubis compiler) */ int main(int argc, char **argv) { -// if(sizeof(int) != 4) + if(sizeof(long) != 4) { - printf("WARNING: 'int' have a size of %d bytes!\n", sizeof(int)); + printf("WARNING: 'long' have a size of %d bytes!\n", sizeof(long)); } /* check if we don't have too many virtual machine instructions */ diff --git a/anubis_dev/extensions/cipher/base64.cpp b/anubis_dev/extensions/cipher/base64.cpp index 12136f1..06a127c 100644 --- a/anubis_dev/extensions/cipher/base64.cpp +++ b/anubis_dev/extensions/cipher/base64.cpp @@ -1,4 +1,3 @@ -#include "stdafx.h" #include /* ENCODE -- Encode binary file into base64. */ @@ -91,6 +90,7 @@ int b64_StreamEncode (struct buffer_st *b, const unsigned char *source, size_t l { encodeblock(source, ptr); source += 3; + src_offset += 3; } ptr += 4; dst_offset += 4; @@ -105,10 +105,10 @@ int b64_StreamEncode (struct buffer_st *b, const unsigned char *source, size_t l { igroup[inPos] = (unsigned char) *source++; src_offset++; + len++; } else igroup[inPos] = 0; - len++; } encodeblock(igroup, ptr); if (len < 3) @@ -210,14 +210,14 @@ int b64_StreamDecode (struct buffer_st *b, const unsigned char *source, size_t l if(len == 4 || finalize) { decodeblock(igroup, ptr); - ptr += len; - dst_offset += len; + ptr += len - 1; + dst_offset += len - 1; } else { for(int i = 0; i < (int)len; i++) b->input[i] = igroup[i]; - b->input_length = len; + b->input_length = len - 1; } } inPos = 0; @@ -256,26 +256,27 @@ void b64_del_buffer(void * handle) } /* parameters are: + - 1 dummy octet inserted by serialization of mixed type (Opaque, Bool, ByteArray) - Opaque(struct buffer_st *) (12 bytes) - Boolean : finalize flag (1 byte) - ByteArray : input data (4 + n bytes) */ int b64_encode(const void * input, size_t in_size, void * output, size_t * out_size) { - if(in_size < 12 + 1 + 4) + if(in_size < 1 + 12 + 1 + 4) { fprintf(stderr, "b64_decode: Wrong input parameters\n"); return -1; } - const unsigned char* args = (const unsigned char*)input; + const unsigned char* args = (const unsigned char*)input + 1; if(*(int*)(args+4) != 4) { fprintf(stderr, "b64_decode: Incoherent input data. Call aborted.\n"); return -1; } - struct buffer_st * b = (struct buffer_st *)(args + 8); + struct buffer_st * b = *(struct buffer_st **)(args + 8); bool finalize = *(args + 12) != 0; size_t input_size = *(const size_t*)(args + 13); const unsigned char * input_buffer = args + 13 + 4; @@ -298,20 +299,20 @@ int b64_encode(const void * input, size_t in_size, void * output, size_t * out_s */ int b64_decode(const void * input, size_t in_size, void * output, size_t * out_size) { - if(in_size < 12 + 1 + 4) + if(in_size < 1+12 + 1 + 4) { fprintf(stderr, "b64_decode: Wrong input parameters\n"); return -1; } - const unsigned char* args = (const unsigned char*)input; + const unsigned char* args = (const unsigned char*)input + 1; if(*(int*)(args+4) != 4) { fprintf(stderr, "b64_decode: Incoherent input data. Call aborted.\n"); return -1; } - struct buffer_st * b = (struct buffer_st *)(args + 8); + struct buffer_st * b = *(struct buffer_st **)(args + 8); bool finalize = *(args + 12) != 0; size_t input_size = *(const size_t*)(args + 13); const unsigned char * input_buffer = args + 13 + 4; diff --git a/anubis_dev/extensions/cipher/base64.h b/anubis_dev/extensions/cipher/base64.h index cc38195..27757b8 100644 --- a/anubis_dev/extensions/cipher/base64.h +++ b/anubis_dev/extensions/cipher/base64.h @@ -13,9 +13,9 @@ void buffer_delete (struct buffer_st *b); int b64_StreamEncode (struct buffer_st *b, const unsigned char *source, size_t length, unsigned char *target, size_t * target_size, bool finalize); int b64_StreamDecode (struct buffer_st *b, const unsigned char *source, size_t length, unsigned char *target, size_t * target_size, bool finalize); -int CIPHER_API b64_init(void * input, size_t in_size, void * output, size_t * out_size); -void CIPHER_API b64_del_buffer(void * handle); -int CIPHER_API b64_encode(const void * input, size_t in_size, void * output, size_t * out_size); -int CIPHER_API b64_decode(const void * input, size_t in_size, void * output, size_t * out_size); +extern "C" int CIPHER_API b64_init(void * input, size_t in_size, void * output, size_t * out_size); +extern "C" void CIPHER_API b64_del_buffer(void * handle); +extern "C" int CIPHER_API b64_encode(const void * input, size_t in_size, void * output, size_t * out_size); +extern "C" int CIPHER_API b64_decode(const void * input, size_t in_size, void * output, size_t * out_size); #endif \ No newline at end of file diff --git a/anubis_dev/library/cipher/base64.anubis b/anubis_dev/library/cipher/base64.anubis new file mode 100644 index 0000000..7792706 --- /dev/null +++ b/anubis_dev/library/cipher/base64.anubis @@ -0,0 +1,102 @@ +/* + * Created by PyramIDE. + * User: ricard + * Date: 04/01/2009 + * Time: 21:13 + * + */ + +read tools/basis.anubis + +public type Base64: + base64(Library library, + Opaque(Base64) handle). + + +public define Result(LibraryError, Base64) + base64_prepare + = + if load_library("cipher.dll") is + { + error(err) then error(cant_load_library), + ok(lib) then + if extension_library_call(lib, "b64_init", constant_byte_array(0,0), 12) is + { + error(err) then error(err), + ok(ba) then + if (Maybe(Opaque(Base64)))unserialize(ba) is + { + failure then error(unknown_error), + success(handle) then ok(base64(lib, handle)) + } + } + }. + +define String + lib_error_to_string + ( + LibraryError err + )= + if err is + { + cant_load_library then "Can't load library.", + symbol_not_found then "Symbol not found.", + external_call_failed then "External call failed.", + unknown_error then "Unknown error." + }. + + +public define String + base64_encode + ( + Base64 b64, + ByteArray input, + Bool finalize + ) = + if b64 is base64(lib, handle) then + if extension_library_call(lib, "b64_encode", serialize((handle, finalize, input)), length(input) \ 3 * 4 + 4 + 1) is + { + error(err) then + println("Can't encode data to base64"); + println(" --> " + lib_error_to_string(err)); + constant_string(0,0), + ok(ba) then to_string(ba) + }. + +public define ByteArray + base64_decode + ( + Base64 b64, + String input, + Bool finalize + ) = + if b64 is base64(lib, handle) then + if extension_library_call(lib, "b64_decode", serialize((handle, finalize, to_byte_array(input))), length(input) \ 4 * 3 + 3) is + { + error(err) then + println("Can't decode data from base64"); + println(" --> " + lib_error_to_string(err)); + constant_byte_array(0,0), + ok(ba) then ba + }. + + +global define One + test_quick_base64 + ( + List(String) args + ) = + with mb_lib = load_library("cipher.dll"), + if base64_prepare is + { + error(err) then + println("Can't prepare base64"); + println(" --> " + lib_error_to_string(err)), + ok(b64) then + with src = "Test of Base64", + encoded = base64_encode(b64, to_byte_array(src), true), + decoded = base64_decode(b64, encoded, true), + result = if to_string(decoded) = src then "OK" else "ERROR", + println(result + "\n source = " + src + "\n encoded = " + encoded + "\n decoded = " + to_string(decoded)) + }. + diff --git a/anubis_dev/library/predefined.anubis b/anubis_dev/library/predefined.anubis index 6f418c2..8a4c3e0 100644 --- a/anubis_dev/library/predefined.anubis +++ b/anubis_dev/library/predefined.anubis @@ -4533,9 +4533,10 @@ public define MakeFastLexerResult public type Library:... an opaque type public type LibraryError: + cant_load_library, symbol_not_found, external_call_failed, - unknown_errro. + unknown_error. public define Result((Word32, String), Library) load_library diff --git a/anubis_dev/library/test/Anubis UnitTest.aproj b/anubis_dev/library/test/Anubis UnitTest.aproj index c4fc242..88d959e 100644 --- a/anubis_dev/library/test/Anubis UnitTest.aproj +++ b/anubis_dev/library/test/Anubis UnitTest.aproj @@ -33,6 +33,7 @@ + diff --git a/anubis_dev/library/test/Anubis UnitTest.ide b/anubis_dev/library/test/Anubis UnitTest.ide index 407a77d..3f655c7 100644 --- a/anubis_dev/library/test/Anubis UnitTest.ide +++ b/anubis_dev/library/test/Anubis UnitTest.ide @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 -# SharpDevelop 1.0.9.98 +# SharpDevelop 1.0.10.102 Project("{B6712916-30DE-4a3e-A54C-2A79AC984AEE}") = "Anubis UnitTest", "Anubis UnitTest.aproj", "{B3F890FB-FBDA-46B4-92E8-9AF1EC349AD2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Library", "Library", "{1F556345-E955-43F3-9BAC-EA0091627D9C}" @@ -11,6 +11,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Library", "Library", "{1F55 ..\compil_all_beta.anubis = ..\compil_all_beta.anubis EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cipher", "cipher", "{FD164ED1-E39F-4527-994C-F372A2BC59F5}" + ProjectSection(SolutionItems) = postProject + ..\cipher\base64.anubis = ..\cipher\base64.anubis + EndProjectSection +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{98405377-F929-4D76-AB66-6F0F4E98F0F9}" ProjectSection(SolutionItems) = postProject ..\examples\_99_bottles_of_beer.anubis = ..\examples\_99_bottles_of_beer.anubis @@ -269,6 +274,7 @@ Global {0BAB369E-80F2-48CA-9F23-DEED6011B642} = {1F556345-E955-43F3-9BAC-EA0091627D9C} {C6AD752D-2943-48FB-A3A2-2D1E3E4DEE2C} = {1F556345-E955-43F3-9BAC-EA0091627D9C} {98405377-F929-4D76-AB66-6F0F4E98F0F9} = {1F556345-E955-43F3-9BAC-EA0091627D9C} + {FD164ED1-E39F-4527-994C-F372A2BC59F5} = {1F556345-E955-43F3-9BAC-EA0091627D9C} {BDDBC8EA-A9E2-4D98-8D09-9EE285237CCF} = {98405377-F929-4D76-AB66-6F0F4E98F0F9} {DF34519E-52E5-4068-9E2C-5F79BC3BBEB6} = {98405377-F929-4D76-AB66-6F0F4E98F0F9} {73CFA6CA-4F09-4F16-821F-815471CE8CDA} = {98405377-F929-4D76-AB66-6F0F4E98F0F9} diff --git a/anubis_dev/library/test/all_unit_test.anubis b/anubis_dev/library/test/all_unit_test.anubis index 0975982..0b7979d 100644 --- a/anubis_dev/library/test/all_unit_test.anubis +++ b/anubis_dev/library/test/all_unit_test.anubis @@ -4,6 +4,7 @@ read tools/unit_test.anubis read serialize_test.anubis read test/predefined/decimal_scan.unit_test.anubis read test/predefined/date_and_time.unit_test.anubis +read test/predefined/ByteArray.ut.anubis read test/predefined/Int.unit_test.anubis read test/predefined/sqlite.obsolete.unit_test.anubis read test/predefined/sqlite.unit_test.anubis @@ -29,6 +30,7 @@ define List(UnitTestSuite) make_convert_test_suite, make_message_queue_test_suite, make_wordXX_test_suite, + make_ByteArray_test_suite, make_Int_test_suite, make_decimal_scan_test_suite, make_string_test_suite, diff --git a/anubis_dev/library/test/predefined/ByteArray.ut.anubis b/anubis_dev/library/test/predefined/ByteArray.ut.anubis new file mode 100644 index 0000000..4718c56 --- /dev/null +++ b/anubis_dev/library/test/predefined/ByteArray.ut.anubis @@ -0,0 +1,28 @@ +/* + * Created by PyramIDE. + * User: ricard + * Date: 05/01/2009 + * Time: 11:33 + * + */ + +read tools/unit_test.anubis + +define One + string_to_BA + ( + UnitTestContext ut + ) = + with s = "This is my string.", + ba = to_byte_array(s), + assertIsSame(ut, length(ba), length(s), abs_to_decimal, "Comparing length"); + unique. + + +public define UnitTestSuite + make_ByteArray_test_suite + = + ut_suite("predefined.ByteArray", + [ + ut_fixture("string_to_BA", string_to_BA), + ]). diff --git a/anubis_dev/vm/src/Library.cpp b/anubis_dev/vm/src/Library.cpp index eaaf534..7bafbbc 100644 --- a/anubis_dev/vm/src/Library.cpp +++ b/anubis_dev/vm/src/Library.cpp @@ -95,7 +95,7 @@ Library::Load(const char* libname) mLastError = iwDllErrorCode; mLastErrorStr = iwDllErrorString(mLastError); - LOGERROR("Failed to load shared library '%s': %s", libname, mLastErrorStr.Cstr()); + LOGERROR("Failed to load shared library '%s': %s\n", libname, mLastErrorStr.Cstr()); return mLastError; } diff --git a/anubis_dev/vm/src/syscall.cpp b/anubis_dev/vm/src/syscall.cpp index 577407b..cfab961 100644 --- a/anubis_dev/vm/src/syscall.cpp +++ b/anubis_dev/vm/src/syscall.cpp @@ -11943,7 +11943,7 @@ fflush(stdout); */ syscall_case(dl_find_symbol) { - Library *lib = (Library *)(((U8 *)(*(MAM(m_SP)-1)))+4); + Library *lib = (Library *)(((U32 *)(*(MAM(m_SP)-1)))[1]); const char *symbol_name = ((const char *)(*(MAM(m_SP)-2)))+4; vm_alloc1(MAM(m_R), 2); void * symbol = lib->GetSymbol(symbol_name); @@ -11954,6 +11954,8 @@ fflush(stdout); } else { + LOGERROR("Symbol '%s' not found into library '%s': %d - %s\n", symbol_name, lib->GetName().Cstr(), lib->GetLastError(), lib->GetLastErrorMessage().Cstr()); + vm_free1(MAM(m_R)); MAM(m_R) = 0; /* failure */ } @@ -11983,7 +11985,8 @@ fflush(stdout); { typedef int (*ext_fn_t)(void*, size_t, void*, size_t*); ext_fn_t fnct = (ext_fn_t)(*(MAM(m_SP)-1)); - U8* in_ba = (U8*)*(MAM(m_SP)-2), out_ba = NULL; + U8* in_ba = (U8*)*(MAM(m_SP)-2); + U32 out_ba = 0; size_t in_size = *(((U32*)in_ba) + 1); size_t out_size = 0; @@ -11998,6 +12001,7 @@ fflush(stdout); out_size = (size_t)Anubis_Int_to_C_int(*(MAM(m_SP)-3)); vm_alloc2(MAM(m_R), 2, out_ba, byte_size_to_word_size(4+4+out_size)); } + *(U32*)(out_ba + 4) = out_size; status_t result = B_ERROR; try { @@ -12005,7 +12009,7 @@ fflush(stdout); } catch(...) { - LOGERROR("Exception catched from Extension Library." ); + LOGERROR("Exception catched from Extension Library.\n" ); result = B_ERROR; } switch(result) @@ -12014,17 +12018,24 @@ fflush(stdout); assert(*(U32*)(out_ba + 4) >= out_size); if(*(U32*)(out_ba + 4) < out_size) { - LOGERROR("Extension library call: incoherent output size (buffer size = %d; output size = %d)", *(U32*)(out_ba + 4), out_size); - LOGERROR("Possibly corrupted memory. Output ByteArray will be truncated for security."); + LOGERROR("Extension library call: incoherent output size (buffer size = %d; output size = %d)\n", *(U32*)(out_ba + 4), out_size); + LOGERROR("Possibly corrupted memory. Output ByteArray will be truncated for security.\n"); + vm_free2(MAM(m_R), out_ba); + MAM(m_duc_non_empty) = 0; + MAM(m_R) = 0; } else + { *(U32*)(out_ba + 4) = out_size; + ((U32 *)(MAM(m_R)))[1] = out_ba; + MAM(m_R) |= 1; // Select 'success' alternative + } break; case NEED_MORE_MEMORY: if(MAM(m_duc_non_empty)) { - LOGERROR("Extension library call: NEED_MORE_MEMORY already returned from previous call."); - LOGERROR(" Abording call to prevent infinite loop."); + LOGERROR("Extension library call: NEED_MORE_MEMORY already returned from previous call.\n"); + LOGERROR(" Abording call to prevent infinite loop.\n"); vm_free2(MAM(m_R), out_ba); MAM(m_duc_non_empty) = 0; MAM(m_R) = 0; @@ -12037,10 +12048,11 @@ fflush(stdout); MAM(m_duc_non_empty) = 1; MAM(m_steps) = 0; MAM(m_status) = need_more_memory; + return; } break; default: // all other errors - LOGERROR("Extension library call: ERROR %s returned by library.", result); + LOGERROR("Extension library call: ERROR %d returned by library.\n", result); vm_free2(MAM(m_R), out_ba); MAM(m_duc_non_empty) = 0; MAM(m_R) = 0; -- libgit2 0.21.4