Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid char pointer deference behavior #165

Open
ChAoSUnItY opened this issue Nov 12, 2024 · 1 comment
Open

Invalid char pointer deference behavior #165

ChAoSUnItY opened this issue Nov 12, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@ChAoSUnItY
Copy link
Collaborator

ChAoSUnItY commented Nov 12, 2024

Considering the following code:

#include <stdlib.h>
#include <string.h>

char a[100];

typedef struct {
    char *raw;
} data_t;

void init_data(data_t *data, char *raw) {
    data->raw = raw;
}

int main() {
    strcpy(a, "DATA");
    data_t *data = malloc(sizeof(data_t));
    init_data(data, a);
    
    char *raw = data->raw;
    printf("%c\n", a[0]);
    printf("%c\n", raw[0]);
    printf("%c\n", data->raw[0]);
    
    
    free(data);

    return 0;
}

Using gcc to compile the program and run it, it would output:

D
D
D

But using shecc, it would output:

D
D
�

This happens because of the incorrect deference assembly code.

@ChAoSUnItY ChAoSUnItY added the bug Something isn't working label Nov 12, 2024
@DrXiao
Copy link
Collaborator

DrXiao commented Jan 23, 2025

The test code in the issue #181 makes me think of this issue, and I add the following printf() calls to execute the code and observe the potential bug:

int main() {
    strcpy(a, "DATA");
    data_t *data = malloc(sizeof(data_t));
    init_data(data, a);
    
    char *raw = data->raw;
    printf("%c\n", a[0]);
    printf("%c\n", raw[0]);
    printf("%c\n", data->raw[0]);
+   printf("%c\n", *data->raw);

+   printf("raw = %x\n", raw);
+   printf("data->raw = %x\n", data->raw);
+   printf("&raw[0] = %x\n", &raw[0]);
+   printf("&data->raw[0] = %x\n", &data->raw[0]);
+   printf("data = %x\n", data);
+   printf("&data[0] = %x\n", &data[0]);
    
    free(data);

    return 0;
}
  • GCC
$ gcc -o test test.c
$ ./test
D
D
D
D
raw = 28863040
data->raw = 28863040
&raw[0] = 28863040
&data->raw[0] = 28863040
data = 5f8d62a0
&data[0] = 5f8d62a0
  • shecc
$ qemu-arm out/shecc-stage2.elf -o test test.c
$ qemu-arm test
D
D
�
D
raw = 407ffdcc
data->raw = 407ffdcc
&raw[0] = 407ffdcc
&data->raw[0] = 4080400c
data = 4080400c
&data[0] = 4080400c

It is obvious that &data->raw[0] equals &data[0].

After observing the code snippets in this comment and the comment in the issue #181, I think the potential bug is that using arrow operator and subscripting operator (-> and [ ]) simultaneously may obtain an incorrect object.

In this comment, &data->raw[0] is equivalent to &data[0].

For my comment in the issue (#181) , the statement cur = map->buckets[0] in the for loop equals cur = map->buckets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants