From 8b15351aa253b1aba3c9940425695002da60cd79 Mon Sep 17 00:00:00 2001 From: psychon Date: Thu, 5 Feb 2009 17:11:45 +0000 Subject: [PATCH] HTTPSock: Don't transfer endless static files in PrintFile() This limits the max file size to 16 MiB and makes the read loop stop after it has read as many bytes as GetSize() said the file is long. This fixes an endless loop when trying to transfer endless files like /dev/zero. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1374 726aef4b-f618-498e-8847-2d620e286838 --- HTTPSock.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/HTTPSock.cpp b/HTTPSock.cpp index 8ffd8b00..2000296d 100644 --- a/HTTPSock.cpp +++ b/HTTPSock.cpp @@ -176,13 +176,30 @@ bool CHTTPSock::PrintFile(const CString& sFileName, CString sContentType) { if (bNotModified) { PrintHeader(0, sContentType, 304, "Not Modified"); } else { + unsigned long long iSize = File.GetSize(); + + // Don't try to send files over 16 MiB, because it might block + // the whole process and use huge amounts of memory. + if (iSize > 16 * 1024 * 1024) { + DEBUG("- Abort: File is over 16 MiB big: " << iSize); + PrintErrorPage(500, "Internal Server Error", "File too big"); + return true; + } + char szBuf[4096]; - int iLen = 0; + unsigned long long iLen = 0; + int i; - PrintHeader(File.GetSize(), sContentType); + PrintHeader(iSize, sContentType); - while ((iLen = File.Read(szBuf, 4096)) > 0) { - Write(szBuf, iLen); + // while we haven't reached iSize and read() succeeds... + while (iLen < iSize && (i = File.Read(szBuf, sizeof(szBuf))) > 0) { + Write(szBuf, i); + iLen += i; + } + + if (i < 0) { + DEBUG("- Error while reading file: " << strerror(errno)); } }