Skip to content

Instantly share code, notes, and snippets.

@hborders
Last active March 13, 2017 15:26
Show Gist options
  • Save hborders/03f9f5bc0a7c362f1737d15feb741f2b to your computer and use it in GitHub Desktop.
Save hborders/03f9f5bc0a7c362f1737d15feb741f2b to your computer and use it in GitHub Desktop.
An example of accidental union misuse of a C union with an enum tag to differentiate types
#include <stdio.h>
typedef enum {
FooType,
BarType,
} Type;
typedef struct {
char *f;
char *g;
} Foo;
typedef struct {
int b;
int c;
} Bar;
typedef struct {
Type type;
union {
Foo foo;
Bar bar;
};
} Example;
void printExample(Example example) {
switch (example.type) {
case FooType: {
Foo foo = example.foo;
printf("Foo: %s, %s\n", foo.f, foo.g);
break;
}
case BarType: {
Bar bar = example.bar;
printf("Bar: %d, %d\n", bar.b, bar.c);
break;
}
}
}
void badPrintExample(Example example) {
switch (example.type) {
case FooType: {
Bar bar = example.bar; // mismatched type!
printf("Bar: %d, %d\n", bar.b, bar.c);
break;
}
case BarType: {
Foo foo = example.foo; // mismatched type!
printf("Foo: %s, %s\n", foo.f, foo.g); // this might crash because foo.f might not end in a '\0'
break;
}
}
}
int main(void) {
Example fooExample = {
.type = FooType,
.foo = {
.f = "foo",
.g = "goo",
},
};
Example barExample = {
.type = BarType,
.bar = {
.b = 2,
.c = 3,
},
};
Example badFooExample = {
.type = BarType, // mismatched type!
.foo = {
.f = "foo",
.g = "goo",
},
};
Example badBarExample = {
.type = FooType, // mismatched type!
.bar = {
.b = 2,
.c = 3,
},
};
badPrintExample(fooExample); // prints Bar: <randomish-number 1>, <random-ish number 2>
printExample(badFooExample); // prints Bar: <randomish-number 1>, <random-ish number 2>
badPrintExample(barExample); // crashes on my machine
printExample(badBarExample); // crashes on my machine
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment