-1

I am trying to convert input string from pipe to hexadecimal, the input is 8KB but converted hex is just 6KB, I print out normal input and the correct lines are coming. I also try to write that hex string to shared memory, maybe my problem is the memory pointer but I'm not sure.

But, it prints out hex correctly for small inputs, I am stuck.

String to hex:

void stringtohex(char *input, char *output) {
    int loop;
    int i; 

    i = 0;
    loop = 0;

    while (input[loop] != '\0') {
        sprintf((char*)(output + i), "%02X", input[loop]);
        loop += 1;
        i += 2;
    }
    //insert NULL at the end of the output string
    output[i++] = '\0';
}

Reading part:

    int num;
    char s[BUFFER_SIZE];
    while ((num = read(fd, s, BUFFER_SIZE)) > 0) {     
        //fprintf(stderr, "input: \n%s\n", s);
        int len = strlen(s);
        char hex[(len * 2) + 1];
        stringtohex(s, hex);
        sprintf(ptr_child_2, "%s", hex);
        ptr_child_2 += strlen(hex);
    }

here ptr is a void * mapped to shared memory.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
HARUN SASMAZ
  • 567
  • 1
  • 7
  • 17

1 Answers1

1

Using read to read data into s and then treat s as if it is a string (e.g. you are calling strlen(s);) is wrong. The function read have no knowledge of strings. It simply tries to read BUFFER_SIZE bytes. So you may get less than a string or multiple strings into s in a single read but it's unlikely that you'll get exactly one string (as your code assumes).

Also notice that you never use num in your code. That's also strange as num holds the number of bytes that were actually stored in s. Consider using num to control the number of bytes to convert.

Or if you really want to operate on strings, take a look at fgets instead.

BTW: Check what sprintf returns... you'll find it useful ;-)

BTW: You could also consider strcat instead of sprintf

The correct solution may depend on the input data but something like this:

char* stringtohex(char* input, char* output, int num)
{
    int loop=0;

    while(loop < num)
    {
        sprintf(output, "%02X", input[loop]);
        loop+=1;
        output += 2;
    }

    //insert NULL at the end of the output string
    *output = '\0';
    return output;
}

Reading part note: ptr_child_2 must point to an empty string to start with:

        char RESULT[SOME_SUFFICIENT_BIG_NUMBER] = ""; // Or dynamic allocation  
        char* ptr_child_2 = RESULT;
        int num;
        char s[BUFFER_SIZE];
        while((num = read(fd, s, BUFFER_SIZE)) > 0)
        {     
            ptr_child_2 = stringtohex(s, ptr_child_2, num);
        }
        printf("%s\n", RESULT);
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • I print out ptr, hex but they both look fine. However, after increasing ptr I guess something is lost. – HARUN SASMAZ Feb 17 '20 at 19:00
  • @HARUNSASMAZ Start by printing `num` and `len`. Are they equal? I assume they ain't. – Support Ukraine Feb 17 '20 at 19:09
  • @HARUNSASMAZ How does your input look? Just **one long string** or multiple strings? What is the value of `BUFFER_SIZE`? – Support Ukraine Feb 17 '20 at 19:11
  • buffer size is 64 KB, input file includes 4 paragraphs, only text. output is empty – HARUN SASMAZ Feb 17 '20 at 19:14
  • num = len and strlen(hex) is double of len – HARUN SASMAZ Feb 17 '20 at 19:16
  • it worked fine at the first time, I copied input file and paste to the bottom of file. basically increase the size to its double. input is 13 KB output is 11KB. Maybe I should append end of string when while loop is over? – HARUN SASMAZ Feb 17 '20 at 19:28
  • this is the ptr: void *ptr_child_2 = mmap(0,MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_child_2, 0); – HARUN SASMAZ Feb 17 '20 at 19:31
  • @HARUNSASMAZ aha... `mmap` ... you should have posted that !! Then it's probably a bad idea to change `ptr_child_2`!! Anyway - to start with drop the `mmap` and use a simply char array as destination - like in my example. Then you'll probably see that this code works. After that you can solve the `mmap` problem – Support Ukraine Feb 17 '20 at 19:37
  • what could be the problem then, yeah your way works – HARUN SASMAZ Feb 17 '20 at 19:47
  • `sprintf(output, "%02X", input[loop]);` is a problem when `input[loop] < 0` -possible UB. Recommend using `unsigned char`. – chux - Reinstate Monica Feb 17 '20 at 19:52
  • @HARUNSASMAZ Well, we can't tell you what the problem is when you don't post the relevant code!! Edit your question to include the relevant parts - best if you can post a complete program – Support Ukraine Feb 17 '20 at 20:35