From fb954ac8daf1ae3e31a150056e0e8de3f80591bb Mon Sep 17 00:00:00 2001 From: CastagnaIT Date: Wed, 23 Oct 2024 09:09:17 +0200 Subject: [PATCH] [Playlist][M3U] Fix long line reading --- xbmc/filesystem/File.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++ xbmc/filesystem/File.h | 8 ++++++ xbmc/playlists/PlayListM3U.cpp | 7 +++-- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/xbmc/filesystem/File.cpp b/xbmc/filesystem/File.cpp index 317816d792..9bdb0d43d8 100644 --- a/xbmc/filesystem/File.cpp +++ b/xbmc/filesystem/File.cpp @@ -765,6 +765,67 @@ int64_t CFile::GetPosition() const return -1; } +bool XFILE::CFile::ReadString(std::vector& line) +{ + if (!m_pFile) + return false; + + line.clear(); + + if (m_pBuffer) + { + using traits = CFileStreamBuffer::traits_type; + CFileStreamBuffer::int_type aByte = m_pBuffer->sgetc(); + + while (aByte != traits::eof()) + { + aByte = m_pBuffer->sbumpc(); + + if (aByte == traits::eof()) + break; + + if (aByte == traits::to_int_type('\n')) + { + if (m_pBuffer->sgetc() == traits::to_int_type('\r')) + m_pBuffer->sbumpc(); + break; + } + + if (aByte == traits::to_int_type('\r')) + { + if (m_pBuffer->sgetc() == traits::to_int_type('\n')) + m_pBuffer->sbumpc(); + break; + } + + line.emplace_back(traits::to_char_type(aByte)); + } + + return true; + } + + try + { + // Read by buffer chuncks until to EOL or EOF + do + { + char bufferLine[1025]; + if (!m_pFile->ReadString(bufferLine, sizeof(bufferLine))) // EOF or error + return !line.empty(); + + const size_t length = std::strlen(bufferLine); + line.insert(line.end(), bufferLine, bufferLine + length); + } while (line.back() != '\n' && line.back() != '\r'); + + return true; + } + XBMCCOMMONS_HANDLE_UNCHECKED + catch (...) + { + CLog::Log(LOGERROR, "{} - Unhandled exception", __FUNCTION__); + } + return false; +} //********************************************************************************************* bool CFile::ReadString(char *szLine, int iLineLength) diff --git a/xbmc/filesystem/File.h b/xbmc/filesystem/File.h index c08b80c5b6..95d1eb2c95 100644 --- a/xbmc/filesystem/File.h +++ b/xbmc/filesystem/File.h @@ -72,6 +72,14 @@ public: * or undetectable error occur, -1 in case of any explicit error */ ssize_t Read(void* bufPtr, size_t bufSize); + + /*! + * \brief String reading by line + * \param line[OUT] The line read + * \return True if has success, otherwise false for EOF or error + */ + bool ReadString(std::vector& line); + bool ReadString(char *szLine, int iLineLength); /** * Attempt to write bufSize bytes from buffer bufPtr into currently opened file. diff --git a/xbmc/playlists/PlayListM3U.cpp b/xbmc/playlists/PlayListM3U.cpp index 572bdced77..07927b0048 100644 --- a/xbmc/playlists/PlayListM3U.cpp +++ b/xbmc/playlists/PlayListM3U.cpp @@ -64,8 +64,7 @@ CPlayListM3U::~CPlayListM3U(void) = default; bool CPlayListM3U::Load(const std::string& strFileName) { - char szLine[4096]; - std::string strLine; + std::vector vLine; std::string strInfo; std::vector > properties; @@ -89,9 +88,9 @@ bool CPlayListM3U::Load(const std::string& strFileName) return false; } - while (file.ReadString(szLine, 4095)) + while (file.ReadString(vLine)) { - strLine = szLine; + std::string strLine(vLine.begin(), vLine.end()); StringUtils::Trim(strLine); if (StringUtils::StartsWith(strLine, InfoMarker)) -- 2.11.4.GIT