Back to code

Download

Prestring

Summary

Several key functions in the C string library have the potential to overflow their destination strings. Prestring is a C module which offers an alternative string type which can still be manipulated transparently as a C string, along with methods analogous to the dangerous library methods, except that instead of overflowing, they grow the destination string. However, along with this boon comes the responsibility of a little setup and cleanup. Here is a complete sample (download it here):

#include <stdio.h>
#include "prestring.h"

int main(void)
{
    char* blah = string_new("blah");
    char* winter = string_new("yesterday was the winter of our discontent; ");
    char* yar  = string_new("yar");

    string_copy(blah, winter);
    string_cat(blah, "whew");
    puts(blah);
    string_printf(&yar, "%d %s %f %x %c", 10, "hello", 1.23, 0xf8, blah[18]);
    puts(yar);

    string_fget(yar, stdin);
    puts(yar);

    string_destroy(yar);
    string_destroy(winter);
    string_destroy(blah);
    return 0;
}

The output is:

yesterday was the winter of our discontent; whew
10 hello 1.230000 f8 w
70
[you type a line]
[whatever line you typed is repeated]

Growable strings (prestrings) must be created with string_new and string_destroy must be called on them when they are no longer in use to free the associated memory. Library functions convert according to the following table:

C string functionPrestring functionComments
strcpystring_copyDestination must be addressable
strcatstring_catDestination must be addressable
strlenstring_lengthstring_length is O(1) instead of O(n)
sprintfstring_printfMust add a & before the first argument
fgetsstring_fgetDon't need to specify a maximum size

The above functions take only prestrings for their modified arguments, but take prestrings and C strings for their const arguments (with the exception of string_length). All other standard library functions can be used directly on any mix of prestrings and C strings.

Never shorten a string by inserting null characters. Instead, use string_truncate, which cuts off the end of a string to make the string a specified size. Also never lengthen a string by overwriting the null terminator. To append a string, use string_cat, and to append a single character, use string_ccat.

Troubleshooting

Q. I replaced some strings with prestrings in my code, and now it's crashing! What happened?

A. First, make sure you've replaced every library function in the table above that is used on the string with the corresponding prestring function. Using the C library version of any of these on a prestring is likely to cause a crash. Also, make sure no function that modifies the string is growing or shrinking it by inserting or overwriting null characters. You must use string_truncate and string_cat/string_ccat for this.

Q. After changing some code to use prestrings, I'm experiencing memory leaks. How do I fix these?

A. Because every prestring is dynamically allocated, you have to be careful to always call string_destroy on it when you're done with it. In functions with many return points, this can be tricky. A simple idiom that you may find helpful is to add a goto label near the end of the function, after which you destroy the string, and then change all return statements to gotos, storing the return value in a local variable:

Before:

int stringStuff() {
    char* str = string_new("");
    string_fget(str, stdin);
    if (str[0] == 'b') {
        return 2;
    }
    if (str[2] == 'a') {
        return 7;
    }
    return 0;
}

After:

int stringStuff() {
    char* str = string_new("");
    int result;
    string_fget(str, stdin);
    if (str[0] == 'b') {
        result = 2;
        goto stringStuffCleanup;
    }
    if (str[2] == 'a') {
        result = 7;
        goto stringStuffCleanup;
    }
    result = 0;
stringStuffCleanup:
    string_destroy(str);
    return result;
}

Download

A working vsnprintf library function is required to use string_printf. If you have doubts about whether yours works, this one does:

http://www.ijs.si/software/snprintf/

The files prestring.h and prestring.c comprise the functionality, and prestring-test.c is a demo, with the archive prestring.tar.gz containing all these:

prestring.tar.gz
prestring.h (view html)
prestring.c (view html)
prestring-test.c (view html)

To-Do

In the future, I need to do some of these:

Back to code

Back to main page

All text and images, but not necessarily linked material, on this page ©1998-2006 Derrick Coetzee and Moonflare and may not be reproduced or used for any purpose without prior written permission except where otherwise indicated.