1

I need to convert a JPG image to BASE64 to insertit into a Cassandra Cluster, all that in C, i found this How do I base64 encode (decode) in C? but it seemes to segmentation fault if i Try to put the result of a fRead on the Image, (Non-printable caracters seems to make the problem)

/* ----------------------------------------------------------------------------------Includes DO NOT MODIFY---------------------------------------------------------------------------------------------- */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "cassandra.h"
#include "../headers/other.h"

size_t fileLen;
/* ---------------------------------------------------------------------------------------CONFIG HERE !---------------------------------------------------------------------------------------------------*/

/*                                                                                ---------Connection----------                                                                                           */

const char *server_adress = "127.0.0.1"; /* Insert your server adress here */

const char *keyframe = "hallo"; /* Insert name of the table you want to insert your data into (Must be created) */

const char *table = "blobi"; /* Insert name of the table you want to insert your data into (Must be created) */

const char *column_name1 = "file_name"; /* Insert name of the column for the key input */
const char *column_name2 = "content"; /* Insert name of the column for the blob input */

/*                                                                                ------------Data-------------                                                                                           */

const char *file_path = "/home/nicolas/Pictures/Minions.jpg"; /* Insert the name of the binary to read and input into your table (changes coming soon !) */

/* -------------------------------------------------------------------------------Do not modify beyond this point ----------------------------------------------------------------------------------------*/

void ReadFile(const char *name)
{
  FILE *file;
  unsigned char *buffer;
  char *lobi;

  //Open file                                                                                                                                                                                                
  file = fopen(name , "rb");
  if (!file)
    {
      fprintf(stderr, "Unable to open file %s", name);
      return;
    }

  //Get file length                                                                                                                                                                                          
  fseek(file, 0, SEEK_END);
  fileLen=ftell(file);
  fseek(file, 0, SEEK_SET);

  //Allocate memory                                                                                                                                                                                          
  buffer=(char *)malloc(fileLen+1);
  if (!buffer)
    {
      fprintf(stderr, "Memory error!");
      fclose(file);
      return;
    }

  //Read file contents into buffer                                                                                                                                                                           
  fread(buffer, fileLen, 1, file);
  size_t *output_length;
  lobi = base64_encode(buffer, fileLen, output_length);
  printf("%s\n", lobi);
  fclose(file);
  insert_blob(buffer);
  free(buffer);
}

And here is base64.c

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
                                'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
                                'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
                                'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
                                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
                                'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                                'w', 'x', 'y', 'z', '0', '1', '2', '3',
                                '4', '5', '6', '7', '8', '9', '+', '/'};
static char *decoding_table = NULL;
static int mod_table[] = {0, 2, 1};

void build_decoding_table() {

  decoding_table = malloc(256);

  for (int i = 0; i < 64; i++)
    decoding_table[(unsigned char) encoding_table[i]] = i;
}

char *base64_encode(const unsigned char *data,
                    size_t input_length,
                    size_t *output_length) {

  *output_length = 4 * ((input_length + 2) / 3);

  char *encoded_data = malloc(*output_length);
  if (encoded_data == NULL) return NULL;

  for (int i = 0, j = 0; i < input_length;) {

    uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
    uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
    uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;

    uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;

    encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
    encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
    encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
    encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
  }

  for (int i = 0; i < mod_table[input_length % 3]; i++)
    encoded_data[*output_length - 1 - i] = '=';

  return encoded_data;
}

HAve you got any advice or lib I can use to do this ?

here the backtrace on gdb :

#0  0x00000000004013e4 in base64_encode (data=0x604960 "\377\330\377", <incomplete sequence \340>, input_length=55605, output_length=0x401e20 <__libc_csu_init>) at sources/base64.c:30

#1  0x0000000000401a45 in ReadFile (name=0x401ed0 "/home/nicolas/Pictures/Minions.jpg") at sources/blob_test.c:81

#2  0x0000000000401b2e in main () at sources/blob_test.c:110

Thanks in advance !

Community
  • 1
  • 1
girard_s
  • 119
  • 1
  • 8
  • 3
    "It seems to segmentation fault" is not very precise. Show us your code, that smallest amount that still breaks. – unwind Oct 03 '14 at 08:04
  • There are a dozen different base64 potential solutions in the link you provided. Are we to *guess* which one you tried and is giving you your seg-fault? – WhozCraig Oct 03 '14 at 08:14
  • @WhozCraig I chose the TopAnswer – girard_s Oct 03 '14 at 08:17
  • Ok. so post the code you ported, along with a minimal `main()` that exhibits the same problem. And when you run your code in a debugger and it crashes, the backtrace log would also be helpful. You *did* run this in a debugger, right? – WhozCraig Oct 03 '14 at 08:20
  • @WhozCraig I did , gdb returned me this : 0x00000000004013e4 in base64_encode (data=0x604960 "\377\330\377", , input_length=55605, output_length=0x401e20 <__libc_csu_init>) at sources/base64.c:30 30 *output_length = 4 * ((input_length + 2) / 3); – girard_s Oct 03 '14 at 08:24
  • @WhozCraig for the main() i just call the readFile() and return, nothing else – girard_s Oct 03 '14 at 08:25
  • 2
    Show the real code. Posting fake code is no use whatsoever. Why read into `buffer` and do nothing further with `buffer`? What is `str`? The fact that you post fake code is indicative of your problems. Make a small complete program that compiles and fails. Post that. If you can't get the detail right, if you can't manage to post real code here, how can you expect to get the detail right with the code you pass to the compiler. Details matter. – David Heffernan Oct 03 '14 at 08:26
  • @girard_s update your question with the *backtrace* once that fault happens. I.e. `gdb> bt` use the backtrace cmd. – WhozCraig Oct 03 '14 at 08:28

2 Answers2

3

This is wrong:

size_t *output_length; // declared an indeterminate pointer
lobi = base64_encode(buffer, fileLen, output_length); // sends bogus address

It should be

size_t output_length = 0; // note *NOT* a pointer
lobi = base64_encode(buffer, fileLen, &output_length); // note address-of operator
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • @girard_s no problem. thanks for posting the log and backtrace. now take both and see if you can see how that info was used to conclude the answer I made above. Once you figure it out, remember it the next time similar issues pop up. – WhozCraig Oct 03 '14 at 08:41
0

For anyone use this code for converting image to base64 using C, In base64_encode() function in base64.c, we should

char *encoded_data = malloc(*output_length + 1); //add for null character and add null character after converting:

encoded_data[*output_length] = 0;

Kalana
  • 5,631
  • 7
  • 30
  • 51
TMBAWS
  • 1