Please stop replying to this thread, this is not an OpenBSD problem at all.
> > Reading the documentation on fparseln (and the underlying fgetln) as > well as on strsep, I see two potentially fatal errors in that code. I > stopped trying after noticing the second issue. > > If you can spot one of them, and feel you are unable to spot the > other, please email me (off list) with the one you found and I'll try > to remember the other one for you. (Do not take too long, though, > because I'll probably forget about this after a few days.) > > Note, of course, that solving two problems does not mean that there > are only two problems. > > Thanks, > > -- > Raul > > On Wed, Aug 24, 2016 at 1:39 PM, Pavan Maddamsetti > <[email protected]> wrote: > > Here's the data structure: > > > > struct node { > > unsigned char end; > > unsigned char letter; > > unsigned char nchild; > > struct node **child; > > }; > > > > struct tree { > > struct node *root; > > }; > > > > And the code: > > > > int > > load(struct tree *tree, FILE *fp) > > { > > char *line, *word; > > const char ws[] = " \t"; > > > > while ((line = fparseln(fp, NULL, NULL, NULL, 0))) { > > while ((word = strsep(&line, ws))) > > if (*word) > > load_word(tree, word); > > free(line); > > } > > > > return (ferror(fp)) ? 0 : 1; > > } > > > > int > > load_word(struct tree *tree, char *word) > > { > > struct node *node, *child, **newp; > > unsigned char c, i, j; > > const char *errstr; > > > > if (*word == '\0') { > > errstr = "empty word"; > > goto fail; > > } > > > > node = tree->root; > > while ((c = *word++) != '\0') { > > if (c >= 'A' && c <= 'Z') > > c = c - 'A' + 'a'; > > if (!(c >= 'a' && c <= 'z')) > > continue; > > > > for (i = 0; i < node->nchild; i++) > > if (c <= node->child[i]->letter) > > break; > > > > if (i < node->nchild && c == node->child[i]->letter) { > > node = node->child[i]; > > continue; > > } > > > > if ((child = new(c)) == NULL) { > > errstr = "new error"; > > goto fail; > > } > > > > /* > > if ((newp = reallocarray(node->child, node->nchild+1, > > sizeof(*node->child))) == NULL) > > goto fail; > > node->child = newp; > > node->nchild++; > > > > for (j = node->nchild; j > i; j--) > > node->child[j] = node->child[j-1]; > > node->child[j] = child; > > */ > > > > if ((newp = calloc(node->nchild+1, sizeof(*node->child))) > > == NULL) > > goto fail; > > for (j = 0; j < i; j++) > > newp[j] = node->child[j]; > > newp[j] = child; > > > > for (j = i+1; j < node->nchild+1; i++, j++) > > newp[j] = node->child[i]; > > node->child = newp; > > node->nchild++; > > > > node = child; > > } > > > > node->end = 1; > > return 1; > > fail: > > if (errstr) > > warnx("load: %s", errstr); > > else > > warn("load"); > > return 0; > > } > > > > On 8/24/16, Theo de Raadt <[email protected]> wrote: > >> No way. > >> > >> the bug is in your own code, which you didn't show. > >> > >>> Hi everyone, > >>> > >>> Sorry to trouble the list if this issue turns out to be spurious. I am > >>> a relatively novice C programmer so it may just be my error. However, > >>> I have implemented a program two ways: one using reallocarray() and > >>> the other using calloc(). > >>> > >>> When I use reallocarray() I get the error "in realloc(): error: use > >>> after free 0x..." So I recompiled with -g and ran gdb: > >>> > >>> Program terminated with signal 6, Aborted. > >>> Loaded symbols for /home/pmaddams/<REDACTED> > >>> Reading symbols from /usr/lib/libutil.so.12.1...done. > >>> Loaded symbols for /usr/lib/libutil.so.12.1 > >>> Reading symbols from /usr/lib/libc.so.84.2...done. > >>> Loaded symbols for /usr/lib/libc.so.84.2 > >>> Reading symbols from /usr/libexec/ld.so...done. > >>> Loaded symbols for /usr/libexec/ld.so > >>> #0 0x00000c01badbc87a in thrkill () at <stdin>:2 > >>> 2 <stdin>: No such file or directory. > >>> in <stdin> > >>> > >>> The situation is, I have a sorted array of at most 26 elements > >>> representing the child nodes of a trie. Instead of using a linked list > >>> I have opted to reallocate the array as a new pointer, shift the top > >>> elements away from the insertion index, copy the new element into the > >>> proper location, and assign the new pointer to the old variable. > >>> > >>> Using small files this seems to work just fine. However, my goal is to > >>> read in the entire file from /usr/share/dict/words, 2.4M of text. It > >>> chokes and dies with the above error. But when I reimplement the > >>> allocation routine with calloc() it seems to work fine. > >>> > >>> What information can I provide to help confirm whether this is a bug > >>> in the system, or in my own code? > >>> > >>> Thanks. > >>> > >> > >> > >
