Critpatch sidecar path: lives next to the .svd.bin.z files so directory-level cache cleanup catches both. The opthash binds the patch to the same options blob the surfaces were built against. Defense-in-depth against path traversal: rejects any fluid_name / source_backend containing '/', '\\', or "..". Mirrors the validation in SVDSurfaceSerializer::default_cache_path; without it a caller passi
| 266 | // since `default_cache_dir()` derives the parent dir from |
| 267 | // `getenv("HOME")` (CodeQL tracks this as taint on fopen). |
| 268 | std::filesystem::path critpatch_cache_path_(const std::string& fluid_name, const std::string& source_backend, const std::string& options_canonical) { |
| 269 | const auto unsafe = [](const std::string& s) { |
| 270 | return s.empty() || s.find('/') != std::string::npos || s.find('\\') != std::string::npos || s.find("..") != std::string::npos; |
| 271 | }; |
| 272 | if (unsafe(fluid_name)) { |
| 273 | throw std::invalid_argument("SVDSBTLBackend: invalid fluid_name (must be a bare component name)"); |
| 274 | } |
| 275 | if (unsafe(source_backend)) { |
| 276 | throw std::invalid_argument("SVDSBTLBackend: invalid source_backend"); |
| 277 | } |
| 278 | const std::filesystem::path dir = CoolProp::sbtl::SVDSurfaceSerializer::default_cache_dir(); |
| 279 | const std::uint64_t opthash = opthash_fnv1a_(options_canonical); |
| 280 | // Match the SVDSurface filename pattern <Fluid>.<Source>.<...>.<opthash>.svd.bin.z |
| 281 | // but with .critpatch.bin suffix (no zlib — too small to matter). |
| 282 | std::ostringstream oss; |
| 283 | oss << fluid_name << '.' << source_backend << ".critpatch." << std::hex << opthash << ".bin"; |
| 284 | return dir / oss.str(); |
| 285 | } |
| 286 | |
| 287 | } // namespace |
| 288 |
no test coverage detected