From 7ac711b48903a658f15e3a28b5b23765f0e49f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sat, 29 Nov 2025 17:56:19 +0100 Subject: [PATCH 1/2] fixed #583 - fall back to `GetFileInformationByHandle()` when `GetFileInformationByHandleEx()` fails in `simplecpp::FileDataCache::getFileId()` (#594) Co-authored-by: willenbr24 --- simplecpp.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index ef891eb1..9ce846d9 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -3126,7 +3126,21 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id) if (hFile == INVALID_HANDLE_VALUE) return false; - const BOOL ret = GetFileInformationByHandleEx(hFile, FileIdInfo, &id.fileIdInfo, sizeof(id.fileIdInfo)); + BOOL ret = GetFileInformationByHandleEx(hFile, FileIdInfo, &id.fileIdInfo, sizeof(id.fileIdInfo)); + if (!ret) { + const DWORD err = GetLastError(); + if (err == ERROR_INVALID_PARAMETER || // encountered when using a non-NTFS filesystem e.g. exFAT + err == ERROR_NOT_SUPPORTED) // encountered on Windows Server Core (used as a Docker container) + { + BY_HANDLE_FILE_INFORMATION fileInfo; + ret = GetFileInformationByHandle(hFile, &fileInfo); + if (ret) { + id.fileIdInfo.VolumeSerialNumber = static_cast(fileInfo.dwVolumeSerialNumber); + id.fileIdInfo.FileId.IdentifierHi = static_cast(fileInfo.nFileIndexHigh); + id.fileIdInfo.FileId.IdentifierLo = static_cast(fileInfo.nFileIndexLow); + } + } + } CloseHandle(hFile); From 72ecd546caa0f1d0737ea999d7b989eaa5e44aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sat, 29 Nov 2025 18:47:07 +0100 Subject: [PATCH 2/2] avoid some unchecked pointer dereferences (#593) --- simplecpp.cpp | 24 ++++++++++++------------ simplecpp.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 9ce846d9..8e10ca54 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -984,7 +984,7 @@ void simplecpp::TokenList::constFold() constFoldComparison(tok); constFoldBitwise(tok); constFoldLogicalOp(tok); - constFoldQuestionOp(&tok); + constFoldQuestionOp(tok); // If there is no '(' we are done with the constant folding if (tok->op != '(') @@ -1354,11 +1354,11 @@ void simplecpp::TokenList::constFoldLogicalOp(Token *tok) } } -void simplecpp::TokenList::constFoldQuestionOp(Token **tok1) +void simplecpp::TokenList::constFoldQuestionOp(Token *&tok1) { bool gotoTok1 = false; // NOLINTNEXTLINE(misc-const-correctness) - technically correct but used to access non-const data - for (Token *tok = *tok1; tok && tok->op != ')'; tok = gotoTok1 ? *tok1 : tok->next) { + for (Token *tok = tok1; tok && tok->op != ')'; tok = gotoTok1 ? tok1 : tok->next) { gotoTok1 = false; if (tok->str() != "?") continue; @@ -1373,8 +1373,8 @@ void simplecpp::TokenList::constFoldQuestionOp(Token **tok1) Token * const falseTok = trueTok->next->next; if (!falseTok) throw std::runtime_error("invalid expression"); - if (condTok == *tok1) - *tok1 = (condTok->str() != "0" ? trueTok : falseTok); + if (condTok == tok1) + tok1 = (condTok->str() != "0" ? trueTok : falseTok); deleteToken(condTok->next); // ? deleteToken(trueTok->next); // : deleteToken(condTok->str() == "0" ? trueTok : falseTok); @@ -3241,14 +3241,14 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens, return cache; } -static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token **tok1, simplecpp::MacroMap ¯os, std::vector &files, simplecpp::OutputList *outputList) +static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token *&tok1, simplecpp::MacroMap ¯os, std::vector &files, simplecpp::OutputList *outputList) { - const simplecpp::Token * const tok = *tok1; + const simplecpp::Token * const tok = tok1; const simplecpp::MacroMap::const_iterator it = tok->name ? macros.find(tok->str()) : macros.end(); if (it != macros.end()) { simplecpp::TokenList value(files); try { - *tok1 = it->second.expand(value, tok, macros, files); + tok1 = it->second.expand(value, tok, macros, files); } catch (const simplecpp::Macro::Error &err) { if (outputList) { simplecpp::Output out = { @@ -3264,7 +3264,7 @@ static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token } else { if (!tok->comment) output.push_back(new simplecpp::Token(*tok)); - *tok1 = tok->next; + tok1 = tok->next; } return true; } @@ -3502,7 +3502,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL TokenList inc2(files); if (!inc1.empty() && inc1.cfront()->name) { const Token *inctok = inc1.cfront(); - if (!preprocessToken(inc2, &inctok, macros, files, outputList)) { + if (!preprocessToken(inc2, inctok, macros, files, outputList)) { output.clear(); return; } @@ -3671,7 +3671,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL maybeUsedMacros[rawtok->next->str()].push_back(rawtok->next->location); const Token *tmp = tok; - if (!preprocessToken(expr, &tmp, macros, files, outputList)) { + if (!preprocessToken(expr, tmp, macros, files, outputList)) { output.clear(); return; } @@ -3769,7 +3769,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL const Location loc(rawtok->location); TokenList tokens(files); - if (!preprocessToken(tokens, &rawtok, macros, files, outputList)) { + if (!preprocessToken(tokens, rawtok, macros, files, outputList)) { output.clear(); return; } diff --git a/simplecpp.h b/simplecpp.h index 22f3c19f..15187063 100644 --- a/simplecpp.h +++ b/simplecpp.h @@ -353,7 +353,7 @@ namespace simplecpp { void constFoldComparison(Token *tok); void constFoldBitwise(Token *tok); void constFoldLogicalOp(Token *tok); - void constFoldQuestionOp(Token **tok1); + void constFoldQuestionOp(Token *&tok1); std::string readUntil(Stream &stream, const Location &location, char start, char end, OutputList *outputList); void lineDirective(unsigned int fileIndex, unsigned int line, Location *location);