diff options
author | Jan Dubois <jand@activestate.com> | 1999-10-15 03:14:23 +0200 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1999-10-15 01:14:22 +0000 |
commit | 25685dc7c95e47b94f62c769e3db898f82b0eb99 (patch) | |
tree | 323bf2754b767d494e4db562e9ba7393dc9b6811 /ext | |
parent | 62d10b704aa877d24f326d3b46b7eceb38549c98 (diff) | |
download | perl-25685dc7c95e47b94f62c769e3db898f82b0eb99.tar.gz |
Prevent "Out of memory" error in POSIX's strftime()
Message-ID: <380f61ae.18202914@smtprelay.t-online.de>
p4raw-id: //depot/perl@4382
Diffstat (limited to 'ext')
-rw-r--r-- | ext/POSIX/POSIX.xs | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index 23c38b5e20..59adb2eecb 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -3858,28 +3858,35 @@ strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1) ** If there is a better way to make it portable, go ahead by ** all means. */ - if ( ( len > 0 && len < sizeof(tmpbuf) ) - || ( len == 0 && strlen(fmt) == 0 ) ) { + if ((len > 0 && len < sizeof(tmpbuf)) || (len == 0 && *fmt == '\0')) ST(0) = sv_2mortal(newSVpv(tmpbuf, len)); - } else { + else { /* Possibly buf overflowed - try again with a bigger buf */ - int bufsize = strlen(fmt) + sizeof(tmpbuf); + int fmtlen = strlen(fmt); + int bufsize = fmtlen + sizeof(tmpbuf); char* buf; int buflen; New(0, buf, bufsize, char); - while( buf ) { + while (buf) { buflen = strftime(buf, bufsize, fmt, &mytm); - if ( buflen > 0 && buflen < bufsize ) break; + if (buflen > 0 && buflen < bufsize) + break; + /* heuristic to prevent out-of-memory errors */ + if (bufsize > 100*fmtlen) { + Safefree(buf); + buf = NULL; + break; + } bufsize *= 2; Renew(buf, bufsize, char); } - if ( buf ) { + if (buf) { ST(0) = sv_2mortal(newSVpvn(buf, buflen)); Safefree(buf); - } else { - ST(0) = sv_2mortal(newSVpvn(tmpbuf, len)); } + else + ST(0) = sv_2mortal(newSVpvn(tmpbuf, len)); } } |