I've been irritated for a long time by the mud refusing to boot after
a reboot/crash, due to ~'s in the world files. These tildes have snuck
past smash_tilde(), and I have to admit, it have bugged me that we had
to have such a strict policy regarding their use, that we've completely
banned the use. So I set forth to make a change in fread_string, the
function that chokes on ~'s in the wrong places.
The change makes fread_string terminate reading correctly when a ~ is
ending a line. If it's in the middle or beginning, it continues reading.
A subtle bug is that if a builder puts a ~on the end of a line, they
still make the port unbootable. To prevent this, I've changed the
smash_tilde function, and made sure that all text altering functions
are smash_tilde'd before saving by having genolc_check_string() call
smash_tilde instead of disallowing ~'s completely.
Also, the change fixes an issue with fread_string and dos/windows files,
as
line\r\n
line number 2\r\n
were previously translated to "line\r\r\nline number 2\r\r\n" and
not the correct "line\r\nline number 2\r\n"
And to sum it all up, it fixes a potential overrun on tmp.
db.c:
/* read and allocate space for a '~'-terminated string from a given file */
char *fread_string(FILE *fl, const char *error)
{
- char buf[MAX_STRING_LENGTH], tmp[512];
+ char buf[MAX_STRING_LENGTH], tmp[514];
char *point;
int done = 0, length = 0, templength;
*buf = '\0';
do {
if (!fgets(tmp, 512, fl)) {
log("SYSERR: fread_string: format error at or near %s", error);
exit(1);
}
/* If there is a '~', end the string; else put an "\r\n" over the '\n'.
*/
- if ((point = strchr(tmp, '~')) != NULL) {
- *point = '\0';
- done = 1;
- } else {
- point = tmp + strlen(tmp) - 1;
- *(point++) = '\r';
- *(point++) = '\n';
- *point = '\0';
- }
+ /* Fix by Welcor:
+ * If the ~ isn't at the end of the string, keep reading.
+ */
+ /* Assumption: the fgets() call above will always contain at least 2
chars */
+ /* namely '\n' and '\0'. "point--" then makes sense.*/
+ point = strchr(tmp, '\0');
+ for (point-- ; (*point=='\r' || *point=='\n'); point--);
+ if (*point=='~') {
+ *point='\0';
+ done = 1;
+ } else {
+ *(++point) = '\r';
+ *(++point) = '\n';
+ *(++point) = '\0';
+ }
templength = point - tmp;
if (length + templength >= MAX_STRING_LENGTH) {
log("SYSERR: fread_string: string too large (db.c)");
log("%s", error);
exit(1);
} else {
strcat(buf + length, tmp); /* strcat: OK (size checked above) */
length += templength;
}
} while (!done);
/* allocate space for the new string and copy it */
return (strlen(buf) ? strdup(buf) : NULL);
}
modify.c:
void smash_tilde(char *str)
{
/*
* Erase any _line ending_ tildes inserted in the editor.
* The load mechanism can't handle those, yet.
* -- Welcor 04/2003
*/
char *p = str;
for (; *p; p++)
if (*p == '~' && (*(p+1)=='\r' || *(p+1)=='\n' || *(p+1)=='\0'))
*p=' ';
}
Welcor
--
+---------------------------------------------------------------+
| FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
| Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
| Newbie List: http://groups.yahoo.com/group/circle-newbies/ |
+---------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 06/26/03 PDT