Question

I want to receive a string, make a reverse and resend it through a socket. The string is encoded with ASN.1.

recv( to_server_socket, &buffer2, sizeof( buffer2 ), MSG_WAITALL );
ber_decode(0, &asn_DEF_Message02, (void**) &message2, buffer2, sizeof buffer2);
xer_fprint(stdout, &asn_DEF_Message02, message2);
printf( "Server --> %d\n", message2->number );  
char* serverString = message2->string.buf;
    int byte_count = message2->string.size;
    char reverseString[50];
    int i=0;
    for(i=0; i < byte_count; ++i)
    {
      char c = serverString[i];
      if(c=='\0')
      {
        reverseString[i] = '\0';
        break;
      }
      else if(c>=65 && c<=90)
        reverseString[i] = c+32;
      else if(c>=97 && c<=122)
        reverseString[i] = c-32;
      else
        reverseString[i] = c;
    }
    printf("String to send: %s\n", reverseString);

I receive the number and the string correctly but when I make the conversion I get some extra caracters like in this output

<Message02>
    <number>35</number>
    <string>Dh3i5KhQNM5OgNh6O</string>
</Message02>
Server --> 35
String to send: dH3I5kHqnm5oGnH6oڹQ
msg3_buf: 
30 16 13 14 64 48 33 49 35 6b 48 71 6e 6d 35 6f 47 6e 48 36 6f ffffffda ffffffb9 51 00 00 <Message03>
    <string>dH3I5kHqnm5oGnH6oڹQ</string>
</Message03>
Was it helpful?

Solution

OK, putting together all the information you have in different questions (e.g. receive and reverse a string asn.1) I've reproduced your problem.

First the solution to the problem: You are not null terminating the reverseString. That's why when you try to print there's garbage after it. Solution is simply to add after the for loop

reverseString[i]='\0';

... I'm not 100% sure that the received string is null terminated (it might, they are probably nice and do it for you)... but even if that's the case, the size field does not include the end-of-string '\0'

Now, a bit of background. Your definition (according to the question cited above) is:

Message02 ::= SEQUENCE {
    number INTEGER, -- incremented integer
    string PrintableString (SIZE (10..20)) -- random string
}

In ASN.1 strings there's no need for a null-termination convention for strings, since length of values is always well defined in the Tag-Length-Value structure. In fact, the online compiler you are using handles PrintableString as OCTET STRING, which can give you a hint that everything is being treated as a raw buffer.

So, for example if you sent number=100 and string="Hello World" you will get in the DER encoding:

30 10 // 0x30 = SEQUENCE, 0x10 = Length 16
   02 01 64  // 0x02 = INTEGER, 0x01 = Lenght 1, 0x64= Value 100
   13 0b 48 65 6c 6c 6f 20 57 6f 72 6c 64 // 0x13 = PrintableString 0x0b= Length 11, value= "Hello World"

I haven't used this compiler for any serious stuff (I've only used to try to reproduce the problem), si I cannot say what is the recommended best practice for OCTETSTRINGS or PrintableStrings, but be wary of char buffer....

Finally, my complete program (instead of sending it through a socket, I'm encoding to a buffer and decoding from the same buffer)

#include "Message02.h"
#include <string.h>


#define BUFFERSIZE 100

int main() {
    Message02_t *message1;
    char buffer2[BUFFERSIZE];
    int ival=100;
    char *sval="Hello World";

    message1 = calloc(1, sizeof(Message02_t));
    message1->number = 100;
    message1->string.buf = sval;
    message1->string.size = strlen(sval);
    der_encode_to_buffer(&asn_DEF_Message02, message1, buffer2, BUFFERSIZE);

    //receive Message02
    Message02_t *message2 = 0;
    message2 = calloc(1, sizeof(Message02_t));
    //recv( to_server_socket, &buffer2, sizeof( buffer2 ), MSG_WAITALL );
    ber_decode(0, &asn_DEF_Message02, (void**) &message2, buffer2, sizeof buffer2);
    xer_fprint(stdout, &asn_DEF_Message02, message2);
    printf( "received number %d\n", message2->number );
    printf( "received String %s\n", message2->string.buf );
    printf( "received String size %d\n", message2->string.size );

    int j;
    for(j=0;j<BUFFERSIZE;j++) {
       printf("%02x",buffer2[j]);
    }
    printf("\n");

    char* serverString = message2->string.buf;
    int byte_count = message2->string.size;
    char reverseString[50];
    int i=0;
    for(i=0; i < byte_count; ++i)
    {
      char c = serverString[i];
      if(c=='\0')
      {
        reverseString[i] = '\0';
        break;
      }
      else if(c>=65 && c<=90)
        reverseString[i] = c+32;
      else if(c>=97 && c<=122)
        reverseString[i] = c-32;
      else
        reverseString[i] = c;
    }
    reverseString[i]='\0'; /* <=== THIS IS THE FIX */
    printf("String to send: %s\n", reverseString);

}

OTHER TIPS

The following line is likely faulty:

int byte_count = message2->string.size;

The string.size likely isn't what you expect. This is probably the storage size of the buffer, and not the length of the string inside the buffer.

This is why you see ffffffda etc. (they are negative numbers, you're subtracting from 0, most likely).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top