Re: rgetmsg (esql/c) can lead one astray
Posted in 1996
>From: tom dorgan <amidasws@rmi.net> >Date: Thu, 03 Oct 1996 09:33:35 -0600 >X-Informix-List-Id: <news.28828> > >in esql/c if you call the rgetmsg function which "converts an Informix >error mesage number into the corresponding message text string" and then >send the string straight out via {f,v}printf, you will get a core dump >in certain cases as what you get back can contain format strings that >the printf routines take to indicate that you will be sending further >arguments for. example: >I got back "Error in the column name %s". sending that directly to >printf dumps core as printf is looking for something to %s print. > >pretty nifty trick. Maybe this has been changed in after 4.0 No, it hasn't changed. That was not what you were intended to do. The standard example code for handling an error message uses sqlca.sqlerrm too, and the post-6.00 code uses rgetlmsg(): { char buffer[512]; int msglen; fflush(stdout); rgetlmsg(sqlca.sqlcode, buffer, sizeof(buffer), &msglen); fprintf(stderr, "SQL %ld: ", sqlca.sqlcode); /* Optional */ fprintf(stderr, buffer, sqlca.sqlerrm); if (sqlca.sqlerrd[1] != 0) { rgetlmsg(sqlca.sqlerrd[1], buffer, sizeof(buffer), &msglen); fprintf(stderr, "ISAM %ld: ", sqlca.sqlerrd[1]); /* Optional */ fprintf(stderr, buffer, sqlca.sqlerrm); } } The key point is that you use sqlca.sqlerrm as the parameter to printf that supplies data for a single %s in the message. Even this is not foolproof; if the error message you receive has more than one %s or a %d instead of a %s, then this will still crash. Most such messages should never be seen in your code; they should correspond to messages generated internally by various programs. But if you want to be really picky, you scan the result string for % symbols and check that there is only one, and that it is followed by an 's', etc... Note that you can (and maybe should) get fancy and test that msglen is less than sizeof(buffer) after the call to rgetlmsg (it is a result parameter) and you should also check that rgetlmsg() succeeded. Yours, Jonathan Leffler (johnl@informix.com) #include <disclaimer.h>