Potential bug in MT4 encrypt/decrypt library

 

When I published my code to protect an indicator / expert adviser I noticed an 'issue' I could not resolve.  It is with the CryptDecode() function when decoding a BASE64 string.

If I encode a plain text string to BASE64 and then immediately decode that string, I get the same result.  As it should be.

int OnInit()
{
   string   PlainText = "This is a BASE64 test";
   uchar    dst[], newdst[], src[], key[];

   // Convert PlainText to character array
   StringToCharArray(PlainText, src);
   
   // Make sure my key is clear
   ArrayInitialize(key, 0x00);
   
   // Reset last error
   ResetLastError();
   
   // Encode plain text to base 64
   if(CryptEncode(CRYPT_BASE64, src, key, dst) == 0)
      Print("Error encoding = ", GetLastError());

   // Reset last error
   ResetLastError();
   
   // Now decode the encoded text
   if(CryptDecode(CRYPT_BASE64, dst, key, newdst) == 0)
      Print("Error decoding = ", GetLastError());
   else
      Print(CharArrayToString(newdst));
}

However, if I take a BASE64 encoded string as the input to the program and try to decode it, I *ALWAYS* get an error 4029 (Invalid array) error code.  The code would be as follows:

// Define input parameter
extern string     Input;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   string   PlainText = "This is a BASE64 test";
   uchar    dst[], src[], key[];

   // Make sure my key is clear
   ArrayInitialize(key, 0x00);
   
   // Reset last error
   ResetLastError();

   // Convert input to character array   
   StringToCharArray(Input, scr);
      
   // Now decode the encoded text
   if(CryptDecode(CRYPT_BASE64, src, key, dst) == 0)
      Print("Error decoding = ", GetLastError());
   else
      Print(CharArrayToString(dst));
      
   if(CharArrayToString(dst) != PlainText)
      Print("Decoded text does not match");
   else
      Print("Decode gave same results");
}

I welcome any and all comments to this issue.

 

Thanks!

-Claude. 

 
Claude Beaudoin:

When I published my code to protect an indicator / expert adviser I noticed an 'issue' I could not resolve.  It is with the CryptDecode() function when decoding a BASE64 string.

If I encode a plain text string to BASE64 and then immediately decode that string, I get the same result.  As it should be.

However, if I take a BASE64 encoded string as the input to the program and try to decode it, I *ALWAYS* get an error 4029 (Invalid array) error code.  The code would be as follows:

I welcome any and all comments to this issue.

 

Thanks!

-Claude. 

thanks for updating,i am reading and following you interestingly.

regards

 
Claude Beaudoin:

When I published my code to protect an indicator / expert adviser I noticed an 'issue' I could not resolve.  It is with the CryptDecode() function when decoding a BASE64 string.

If I encode a plain text string to BASE64 and then immediately decode that string, I get the same result.  As it should be.

However, if I take a BASE64 encoded string as the input to the program and try to decode it, I *ALWAYS* get an error 4029 (Invalid array) error code.  The code would be as follows:

I welcome any and all comments to this issue.

 

Thanks!

-Claude. 

Because you need to drop the ending '0' character.

   StringToCharArray(Input,src);
   ArrayResize(src,32);
I will let you generalize the solution
 
Alain Verleyen:

Because you need to drop the ending '0' character.

I will let you generalize the solution
Thanks Alain.  I had a feeling you were the one that was going to answer this :)
 
Claude Beaudoin:
Thanks Alain.  I had a feeling you were the one that was going to answer this :)
Yeah...it's not funny, always the same
 
Alain Verleyen:
Yeah...it's not funny, always the same

I know you are one of the top coders here and your input/comments are greatly appreciated by the community (even if you don't always get the "Thanks" you deserve).

But would it not make sense to omit the null character when converting a string to a character array?  So the real bug would be in the StringCharToArray()  function.  We know that a string is always terminated by a null character, but a character array does not need the null character.  So the function should strip that null character when converting a string to an array.

Your thought?

Thanks.

 
Claude Beaudoin:

I know you are one of the top coders here and your input/comments are greatly appreciated by the community (even if you don't always get the "Thanks" you deserve).

Thanks, much appreciated.

But would it not make sense to omit the null character when converting a string to a character array?  So the real bug would be in the StringCharToArray()  function.  We know that a string is always terminated by a null character, but a character array does not need the null character.  So the function should strip that null character when converting a string to an array.

Your thought?

Thanks.

Yes, you can think about it like a bug in StringCharToArray(), but please don't report it to Metaquotes, they are able to fix it and broke existing codes

More seriously it's not a bug, it works as documented, and you could also specify the length of the string as a parameter to avoid the terminal 0.

 
Claude Beaudoin:

When I published my code to protect an indicator / expert adviser I noticed an 'issue' I could not resolve.  It is with the CryptDecode() function when decoding a BASE64 string.

If I encode a plain text string to BASE64 and then immediately decode that string, I get the same result.  As it should be.

However, if I take a BASE64 encoded string as the input to the program and try to decode it, I *ALWAYS* get an error 4029 (Invalid array) error code.  The code would be as follows:

I welcome any and all comments to this issue.

 

Thanks!

-Claude. 


A trivial question as i don't have test this... but if you decode the code that contents another functions where do you print it in order to work? I mean, outside the Ontick function?

Thanks.

Regards