For pleasure, I wrote an attempt that tries to guess based on the addresses of other literals. It works by comparing the address of a potential literal with another known literal, the stack address and the heap address. If the potential address is closer to the literal than the others, it assumes that the potential address is a literal. In practice, this is probably unreliable. Here is a simplified version:
int is_literal_simplistic(char *s) {
char *literal = "literal";
char stack[] = "stack";
char *heap = malloc(1);
free(heap);
unsigned long literal_delta = labs(literal - s);
unsigned long stack_delta = labs(stack - s);
unsigned long heap_delta = labs(heap - s);
return (literal_delta < stack_delta && literal_delta < heap_delta);
}
here is a shorter version. Perhaps this will be easier:
int is_literal(char *s) {
char *heap = malloc(1);
free(heap);
unsigned long literal_delta = labs("literal" - s);
unsigned long stack_delta = labs((char *)&s - s);
unsigned long heap_delta = labs(heap - s);
return (literal_delta < stack_delta && literal_delta < heap_delta);
}
Full test:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#ifdef DEBUG
void debug_literal(unsigned long literal,
unsigned long stack,
unsigned long heap,
unsigned long literal_delta,
unsigned long stack_delta,
unsigned long heap_delta) {
printf("literal(%lx) stack(%lx) heap(%lx)\n", literal, stack, heap);
printf("literal(%lu) stack(%lu) heap(%lu)\n", literal_delta, stack_delta, heap_delta);
int answer = (literal_delta < stack_delta && literal_delta < heap_delta);
printf("\t%s\n", answer ? "literal" : "other");
}
#else
void debug_literal(unsigned long literal,
unsigned long stack,
unsigned long heap,
unsigned long literal_delta,
unsigned long stack_delta,
unsigned long heap_delta) {
}
#endif
int is_literal_simplistic(char *s) {
char *literal = "literal";
char stack[] = "stack";
char *heap = malloc(1);
free(heap);
unsigned long literal_delta = labs(literal - s);
unsigned long stack_delta = labs(stack - s);
unsigned long heap_delta = labs(heap - s);
debug_literal((unsigned long)literal, (unsigned long)stack, (unsigned long)heap,
literal_delta, stack_delta, heap_delta);
return (literal_delta < stack_delta && literal_delta < heap_delta);
}
int is_literal(char *s) {
char *heap = malloc(1);
free(heap);
unsigned long literal_delta = labs("literal" - s);
unsigned long stack_delta = labs((char *)&s - s);
unsigned long heap_delta = labs(heap - s);
debug_literal(0,0,0, literal_delta, stack_delta, heap_delta);
return (literal_delta < stack_delta && literal_delta < heap_delta);
}
void test_literal_function(int(*liternal_fn)(char *)) {
char *literal = "literal_test";
char stack[] = "stack_test";
char *heap = malloc(40);
printf("\t%s\n", liternal_fn(literal) ? "literal" : "other");
printf("\t%s\n", liternal_fn(stack) ? "literal" : "other");
printf("\t%s\n", liternal_fn(heap) ? "literal" : "other");
printf("\n");
free(heap);
}
int main() {
test_literal_function(is_literal_simplistic);
test_literal_function(is_literal);
return 0;
}