DF-5675 / df5675_userland.c
/* * DF-5675 — userland differential against the SAME libprop source that is * compiled into the kernel (/usr/src/sys/libprop). * * internalize(depth=N) -> iterative, SUCCEEDS for any N (prints count) * externalize() -> recursive, dies once frames * depth > rlimit * * Run under a small stack rlimit to make the asymmetry visible: * ulimit -s 1024 ; ./df5675_userland 20000 -> SIGSEGV in externalize * ulimit -s 1024 ; ./df5675_userland 300 -> prints both lengths, exit 0 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <libprop/proplib.h> static char * build_deep_plist(int depth, size_t *lenp) { size_t cap = (size_t)depth * 32 + 4096; char *xml = malloc(cap); size_t off = 0; int i; off += sprintf(xml + off, "<plist version=\"1.0\"><dict><key>a</key>"); for (i = 0; i < depth; i++) off += sprintf(xml + off, "<array>"); off += sprintf(xml + off, "<true/>"); for (i = 0; i < depth; i++) off += sprintf(xml + off, "</array>"); off += sprintf(xml + off, "</dict></plist>"); *lenp = off; return (xml); } int main(int argc, char **argv) { int depth = argc > 1 ? atoi(argv[1]) : 20000; prop_dictionary_t dict; char *xml, *out; size_t len; xml = build_deep_plist(depth, &len); fprintf(stderr, "internalize depth=%d (%zu bytes xml)...\n", depth, len); dict = prop_dictionary_internalize(xml); if (dict == NULL) { fprintf(stderr, "internalize FAILED (parser rejected depth)\n"); return (1); } fprintf(stderr, "internalize OK (iterative parser handles any depth)\n"); fprintf(stderr, "externalize (recursive)...\n"); fflush(stderr); out = prop_dictionary_externalize(dict); if (out == NULL) { fprintf(stderr, "externalize returned NULL (no crash)\n"); return (2); } fprintf(stderr, "externalize OK, output %zu bytes (no crash)\n", strlen(out)); free(out); prop_object_release(dict); return (0); } |