Last active
March 13, 2017 15:26
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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