diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 9a99fc7..e6b0dfb 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -2699,41 +2699,53 @@ static char * expand_fmt_string(const char *fmt, ErrorData *edata) { StringInfoData buf; - const char *cp; + const char *cp = fmt; initStringInfo(&buf); - for (cp = fmt; *cp; cp++) + for (;;) { - if (cp[0] == '%' && cp[1] != '\0') + const char *s = cp; + + /* Copy data in bulk until we reach a %-escape. */ + while (*s != '\0' && *s != '%') + ++s; + appendBinaryStringInfo(&buf, cp, s - cp); + cp = s; + + /* If we've reached the end of the string, get out. */ + if (cp[0] == '\0') + break; + if (cp[1] == '\0') { - cp++; - if (*cp == 'm') - { - /* - * Replace %m by system error string. If there are any %'s in - * the string, we'd better double them so that vsnprintf won't - * misinterpret. - */ - const char *cp2; - - cp2 = useful_strerror(edata->saved_errno); - for (; *cp2; cp2++) - { - if (*cp2 == '%') - appendStringInfoCharMacro(&buf, '%'); - appendStringInfoCharMacro(&buf, *cp2); - } - } - else + appendStringInfoCharMacro(&buf, cp[0]); + break; + } + + if (cp[1] == 'm') + { + /* + * Replace %m by system error string. If there are any %'s in + * the string, we'd better double them so that vsnprintf won't + * misinterpret. + */ + const char *cp2; + + cp2 = useful_strerror(edata->saved_errno); + for (; *cp2; cp2++) { - /* copy % and next char --- this avoids trouble with %%m */ - appendStringInfoCharMacro(&buf, '%'); - appendStringInfoCharMacro(&buf, *cp); + if (*cp2 == '%') + appendStringInfoCharMacro(&buf, '%'); + appendStringInfoCharMacro(&buf, *cp2); } } else - appendStringInfoCharMacro(&buf, *cp); + { + /* copy % and next char --- this avoids trouble with %%m */ + appendStringInfoCharMacro(&buf, '%'); + appendStringInfoCharMacro(&buf, cp[1]); + } + cp += 2; } return buf.data;