How do I work with msgpack_pack_raw and msgpack_pack_raw_body to send an unsigned char array to more importantly, how to retrieve (unpack) it?
What I have done is as follows:
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
msgpack_sbuffer_clear(buffer);
msgpack_pack_array(pk, 10);
unsigned char a[10] = "0123456789";
msgpack_pack_raw(pk, 10);
msgpack_pack_raw_body(pk,a,10);
and in the receiver part I have:
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
msgpack_unpack_next(&msg, buffer->data, buffer->size, NULL);
msgpack_object obj = msg.data;
msgpack_object* p = obj.via.array.ptr;
int length = (*p).via.raw.size;
IDPRINT(length);
unsigned char* b = (unsigned char*) malloc(length);
memcpy(b,(*p).via.raw.ptr,length);
But it throws seg fault when executing "int length = (*p).via.raw.size;".
Any idea why?
Any idea why?
This is because msgpack_pack_array(pk, 10); is not required here, since you pack your data as a raw buffer of a given size. In other words msgpack_pack_raw and msgpack_pack_raw_body are sufficient.
At unpack time, you must access its fields as follow:
length: obj.via.raw.size
data: obj.via.raw.ptr
see: msgpack_object_raw in object.h.
Here's a recap of how to proceed:
#include <stdio.h>
#include <assert.h>
#include <msgpack.h>
int main(void) {
unsigned char a[10] = "0123456789";
char *buf = NULL;
int size;
/* -- PACK -- */
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pck;
msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);
msgpack_pack_raw(&pck, 10);
msgpack_pack_raw_body(&pck, a, 10);
size = sbuf.size;
buf = malloc(sbuf.size);
memcpy(buf, sbuf.data, sbuf.size);
msgpack_sbuffer_destroy(&sbuf);
/* -- UNPACK -- */
unsigned char *b = NULL;
int bsize = -1;
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
if (msgpack_unpack_next(&msg, buf, size, NULL)) {
msgpack_object root = msg.data;
if (root.type == MSGPACK_OBJECT_RAW) {
bsize = root.via.raw.size;
b = malloc(bsize);
memcpy(b, root.via.raw.ptr, bsize);
}
}
/* -- CHECK -- */
assert(bsize == 10);
assert(b != NULL);
for (int i = 0; i < bsize; i++)
assert(b[i] == a[i]);
printf("ok\n");
free(buf);
free(b);
return 0;
}
Related
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <math.h>
#include <time.h>
#define RAND(lower,upper) (rand()%(upper-lower+1))+lower
int power(int base, int exp)
{
int result=1;
while (exp != 0)
{
result *= base;
--exp;
}
return result;
}
int isKthBitSet(int n, int k)//from right, 1<=k<=n
{
int new_num = n >> (k - 1);
// if it results to '1' then bit is set,
// else it results to '0' bit is unset
return (new_num & 1);
}
struct Astructure{
uint16_t bitmap;
uint32_t a;
uint32_t b;
char str[10];
uint16_t d;
}__attribute__((packed));
int main()
{
struct Astructure abitmap;
abitmap.bitmap = 0;
char buffer[(sizeof(struct Astructure))];
abitmap.a = 52;
abitmap.b = 16;
char c[10]={"ramya"};
strcpy(abitmap.str, c);
abitmap.d = 59;
char ch;
srand(time(0));
for(uint8_t position =1;position<5;position++)
{
int random10 = RAND(0,1);
if(random10==1)
{
int value = power(2,position-1);
abitmap.bitmap = abitmap.bitmap | value;
}
}
memcpy(buffer, (char *)&abitmap.bitmap, sizeof(abitmap.bitmap)+1);
uint8_t temp4 = isKthBitSet(abitmap.bitmap,4);
uint8_t temp3 = isKthBitSet(abitmap.bitmap,3);
uint8_t temp2 = isKthBitSet(abitmap.bitmap,2);
uint8_t temp1 = isKthBitSet(abitmap.bitmap,1);
uint8_t previousLength = sizeof(abitmap.bitmap);
if(temp4){
//add a to buffer
memcpy(buffer + previousLength, (void *)&abitmap.a, sizeof(abitmap.a)+1);
previousLength += sizeof(abitmap.a);
}
if(temp3){
//add b to buffer
memcpy(buffer + previousLength, (void *)&abitmap.b, sizeof(abitmap.b)+1);
previousLength += sizeof(abitmap.b);
}
if(temp2){
//add c to buffer
memcpy(buffer + previousLength, (void *)&abitmap.str, sizeof(abitmap.str)+1);
previousLength += sizeof(abitmap.str);
}
if(temp1){
//add d to buffer
memcpy(buffer + previousLength, (char *)&abitmap.d, sizeof(abitmap.d)+1);
previousLength += sizeof(abitmap.d);
}
//SHOW BUFFER
previousLength = sizeof(abitmap.bitmap);
uint32_t a;
uint32_t b;
char str[10];
uint16_t d;
if(temp4){
memcpy(&a , (void *) buffer+previousLength , sizeof(abitmap.a)+1);//
printf("a = %d\t",a);
previousLength += sizeof(a);
}
if(temp3){
memcpy(&b , (void *) buffer+previousLength , sizeof(abitmap.b)+1);
printf("b = %d\t",b);
previousLength += sizeof(b);
}
if(temp2){
memcpy(str , (void *) buffer+previousLength , sizeof(abitmap.str)+1);//memccpy
printf("string = %s\t",str);
previousLength += sizeof(str);
}
if(temp1){
memcpy(&d , (void *) buffer+previousLength , sizeof(abitmap.d)+1);
printf("d = %d\t",d);
previousLength += sizeof(d);
}
printf("\n");
}
I trying to copy some variables to my buffer. The variables I want to add in the buffer is picked at random. Here I gave the size of my buffer before hand to the size of my structure. But as per my program I may not be adding all my variables in the buffer. So its a waste.
So How am I supposed to declare my buffer here.
if my replace this
char buffer[(sizeof(struct Astructure))];
to
char *buffer;
this
I get below error.
a = 52 string = ramya
*** stack smashing detected ***: terminated
Aborted (core dumped)
I dont want to waste the size of my buffer in here, giving the whole size of structure. so what do i do.
If you want to allocate only the required memory:
typedef struct
{
size_t length;
unsigned char data[];
}buff_t;
buff_t *addtobuffer(buff_t *buff, const void *data, size_t size)
{
size_t pos = buff ? buff -> length : 0;
buff = realloc(buff, pos + size + sizeof(*buff));
if(buff)
{
memcpy(buff -> data + pos, data, size);
buff -> length = pos + size;
}
return buff;
}
and example usage:
buff_t *buffer = NULL;
/* ... */
if(temp4)
{
buff_t *tmp = addtobuffer(buffer, &abitmap.a, sizeof(abitmap.a)+1);
if(!tmp) { /* error handling */}
buffer = tmp;
/*...*/
}
I've defined a struct to represent strings and want to make a list from this string-structs. I've coded a function toString, which gets a char pointer and the result is such a string-struct. I've coded a function toList, which gets a pointer of char pointer, makes strings from these char pointers and concatenate these to a list of strings.
Now I want to use these, but I always get this stack error 0 [main] stringL 1123 cygwin_exception::open_stackdumpfile: Dumping stack trace to stringL.exe.stackdump. Could the problem be the assignment with makro? Not even the debug output 0, 1, 2, 3 is printed. I'm thankful for some help.
Code:
#include<stdio.h>
#include<stdlib.h>
#define EMPTYLIST NULL
#define ISEMPTY(l) ((l) == EMPTYLIST)
#define TAIL(l) ((l)->next)
#define HEAD(l) ((l)->str)
typedef struct {
char *str;
unsigned int len;
} String;
typedef struct ListNode *StringList;
struct ListNode {
String str;
StringList next;
};
String toString (char *cstr) {
String res = {NULL, 0};
res.str = malloc(sizeof(char));
char *ptr = res.str;
while(*cstr) {
*ptr++ = *cstr++;
res.str = realloc(res.str, sizeof(char) * (res.len +2));
res.len++;
}
*ptr = '\0';
return res;
}
StringList toList (char **cstrs, unsigned int sc){
if(sc > 0) {
StringList res = malloc(sizeof(*res));
HEAD(res) = toString(*cstrs);
TAIL(res) = toList(cstrs+1, sc+1);
}
return EMPTYLIST;
}
int main() {
printf("0");
char **strs = malloc(sizeof(**strs) *2);
unsigned int i = 0;
char *fst = "Der erste Text";
char *snd = "Der zweite Text";
printf("1");
StringList res = toList(strs, 2);
StringList lstPtr = res;
strs[0] = malloc(sizeof(char) * 15);
strs[1] = malloc(sizeof(char) * 16);
printf("2");
while(*fst) {
strs[0][i] = *fst++;
i++;
}
printf("3");
i = 0;
while(*snd) {
strs[1][i] = *snd++;
i++;
}
printf("Liste: \n");
for(i = 0; i < 2; i++){
printf("Text %d: %s\n", i, HEAD(lstPtr++));
}
return 0;
}
After this statement
res.str = realloc(res.str, sizeof(char) * (res.len +2));
the value stored in the pointer res.str can be changed. As a result the value stored in the pointer ptr after its increment
*ptr++ = *cstr++;
can be invalid and does not point to a place in the reallocated memory.
i wrote a little console program which stores words in an array, represented by char** test_tab, and then print them.
The program works fine as long as it does not go through the conditionalrealloc() (e.g if i increase sizeto 1000).
But if realloc() get called the program crashes during the array printing, probably because the memory is messed up in there.
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
char* get_word();
int main(int argc, char* argv[])
{
size_t size = 100;
size_t nb_pointer = 0;
char** test_tab = malloc(size * sizeof *test_tab);
char** temp_tab;
while((*(test_tab + nb_pointer) = get_word()) != NULL)
{
nb_pointer++;
if(nb_pointer >= size)
{
size += 100;
temp_tab = realloc(test_tab, size);
if(temp_tab != NULL)
test_tab = temp_tab;
else
{
free(test_tab);
exit(1);
}
}
}
for(nb_pointer = 0; *(test_tab + nb_pointer) != NULL; nb_pointer++)
printf("%s\n", *(test_tab + nb_pointer));
free(test_tab);
return 0;
}
Can someone explains me what i am doing wrong right here? Thanks.
The amount of memory in the realloc is not calculated correctly.
temp_tab = realloc(test_tab, size);
should be
temp_tab = realloc(test_tab, size * sizeof *test_tab);
Every time you are trying to push one string and at the same time take all the previously pushed string with you. Now string means char * & hence you need to use sizeof(char*) * size & then you need to allocate the memory to the string again to store the actual character..However you can also approach in this way
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static int size = 0; // static global means no risk while including this file
char** push(char** memptr, char* data) {
size++;
if (size == 1)
memptr = (char**)malloc(size * sizeof(char*));
else
memptr = (char**)realloc(memptr, size* sizeof(char*));
memptr[size - 1] = (char*)malloc(sizeof(char) * strlen(data) + 1);
strncpy(memptr[size - 1], data, strlen(data));
memptr[size - 1][strlen(data) -1] = '\0'; // over writing the `\n` from `fgets`
return memptr;
}
int main() {
char buf[1024];
int i;
static char** memptr = NULL;
for (i = 0; i < 5; i++){
fgets(buf, 1024, stdin);
memptr = push(memptr, buf);
}
for (i = 0; i < size; i++)
printf("%s\n", memptr[i]);
return 0;
}
This is my code (the errors checking were deliberately omitted for code readability):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gcrypt.h>
#define GCRYPT_VERSION "1.5.0"
#define GCRY_CIPHER GCRY_CIPHER_AES128
int main(void){
if(!gcry_check_version(GCRYPT_VERSION)){
fputs("libgcrypt version mismatch\n", stderr);
exit(2);
}
gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
gcry_control(GCRYCTL_RESUME_SECMEM_WARN);
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
int algo = -1;
size_t i;
const char *name = "aes128";
char plain_text[16] = {0x80};
char key[16] = {0};
char iniVector[16] = {0};
size_t txtLenght = strlen(plain_text);
char *encBuffer = malloc(txtLenght);
gcry_cipher_hd_t hd;
algo = gcry_cipher_map_name(name);
size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_CBC, 0);
gcry_cipher_setkey(hd, key, keyLength);
gcry_cipher_setiv(hd, iniVector, blkLength);
gcry_cipher_encrypt(hd, encBuffer, txtLenght, plain_text, txtLenght);
printf("encBuffer = ");
for(i = 0; i < txtLenght; i++){
printf("%02x", (unsigned char) encBuffer[i]);
}
printf("\n");
gcry_cipher_close(hd);
free(encBuffer);
return 0;
}
Expected result:
KEY = 00000000000000000000000000000000
IV = 00000000000000000000000000000000
PLAINTEXT = 80000000000000000000000000000000
CIPHERTEXT = 3ad78e726c1ec02b7ebfe92b23d9ec34
My result:
KEY = 00000000000000000000000000000000
IV = 00000000000000000000000000000000
PLAINTEXT = 80000000000000000000000000000000
CIPHERTEXT = 42
Why i got this output? What am I doing wrong?
You are using ASCII values but the AES test vectors are given as hexadecimal values.
Try with hex values instead (the remaining values of the array are initialized by 0 in C):
char plain_text[16] = {0x80};
char key[16] = {0};
char iniVector[16] = {0};
size_t txtLenght = sizeof plain_text;
Based on my previous post, I came up with the following code. I'm sure there is a better way of doing it. I'm wondering, what would that be?
It does split the string if greater than max chars OR if # is found. Any ideas would be appreciated!
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct my_struct {
char *str;
};
int main () {
struct my_struct *struc;
int max = 5;
char *tmp = "Hello World#Foo Bar In here#Bar Foo dot com#here#there";
struc = malloc (20 * sizeof (struct my_struct));
int strIdx = 0, offSet = 0;
char *p = tmp;
char *tmpChar = malloc (strlen (tmp) + 1), *save;
save = tmpChar;
while (*p != '\0') {
if (offSet < max) {
offSet++;
if (*p == '#') {
if (offSet != 1) {
*tmpChar = '\0';
struc[strIdx++].str = strndup (save, max);
save = tmpChar;
}
offSet = 0;
} else
*tmpChar++ = *p;
} else { // max
offSet = 0;
*tmpChar = '\0';
struc[strIdx++].str = strndup (save, max);
save = tmpChar;
continue;
}
p++;
}
struc[strIdx++].str = strndup (save, max); // last 'save'
for (strIdx = 0; strIdx < 11; strIdx++)
printf ("%s\n", struc[strIdx].str);
for (strIdx = 0; strIdx < 11; strIdx++)
free (struc[strIdx].str);
free (struc);
return 0;
}
Output at 5 chars max:
Hello
Worl
d
Foo B
ar In
here
Bar F
oo do
t com
here
there
Alright, I'll take a crack at it. First, let me say that my formatting changes were for me. If you don't like lonely {s, that's fine.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5
struct string_bin
{
char *str;
};
int main ()
{
struct string_bin *strings;
char *tmp = "Hello World#Foo Bar In here#Bar Foo dot com#here#there";
char *p = tmp;
strings = malloc (20 * sizeof (struct string_bin));
memset(strings, 0, 20 * sizeof (struct string_bin));
int strIdx = 0, offset = 0;
char *cursor, *save;
strings[strIdx].str = malloc(MAX+1);
save = strings[strIdx].str;
while (*p != '\0')
{
if (offset < MAX && *p != '#')
{
*(save++) = *(p++);
offset++;
continue;
}
else if (*p == '#')
*p++;
offset = 0;
*save = '\0';
strings[++strIdx].str = malloc(MAX+1);
save = strings[strIdx].str;
}
*save = '\0';
for (strIdx = 0; strings[strIdx].str != NULL; strIdx++)
{
printf ("%s\n", strings[strIdx].str);
free (strings[strIdx].str);
}
free (strings);
return 0;
}
The big change is that I got rid of your strdup calls. Instead, I stuffed the string directly into its destination buffer. I also made more calls to malloc for individual string buffers. That lets you not know the length of the input string ahead of time at the cost of a few extra allocations.