mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
BugReportTool: replace cziplib with tar.exe (#41127)
BugReportTool is the last consumer in the PowerToys repo of cziplib, a library we use to produce ZIP files. This pull request replaces cziplib with a simple CreateProcess call that spawns `tar.exe`, which comes with Windows as of RS4 and can produce ZIP files! I've tested this by producing a bug report archive and attempting to open it with File Explorer. It works fine. We have taken every precaution to ensure that we do not allow any attacker-controlled input to tar's command line. We are *not* using `system()`, and we are not opening up a vector through which a nefarious caller can perform shell injection. We do not pass filenames to tar except that of the final archive. We do not pass directory names to tar; we rely on the current directory instead.
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -4,6 +4,3 @@
|
|||||||
[submodule "deps/expected-lite"]
|
[submodule "deps/expected-lite"]
|
||||||
path = deps/expected-lite
|
path = deps/expected-lite
|
||||||
url = https://github.com/martinmoene/expected-lite.git
|
url = https://github.com/martinmoene/expected-lite.git
|
||||||
[submodule "deps/cziplib"]
|
|
||||||
path = deps/cziplib
|
|
||||||
url = https://github.com/kuba--/zip.git
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
<PropertyGroup Condition="'$(SkipCppCodeAnalysis)' == ''">
|
<PropertyGroup Condition="'$(SkipCppCodeAnalysis)' == ''">
|
||||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||||
<CodeAnalysisRuleSet>$(MsbuildThisFileDirectory)\CppRuleSet.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>$(MsbuildThisFileDirectory)\CppRuleSet.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CAExcludePath>$(MSBuildThisFileDirectory)deps;$(MSBuildThisFileDirectory)packages;$(CAExcludePath)</CAExcludePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- C++ source compile-specific things for all configurations -->
|
<!-- C++ source compile-specific things for all configurations -->
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
<PreferredToolArchitecture Condition="'$(PROCESSOR_ARCHITECTURE)' == 'ARM64' or '$(PROCESSOR_ARCHITEW6432)' == 'ARM64'">arm64</PreferredToolArchitecture>
|
<PreferredToolArchitecture Condition="'$(PROCESSOR_ARCHITECTURE)' == 'ARM64' or '$(PROCESSOR_ARCHITEW6432)' == 'ARM64'">arm64</PreferredToolArchitecture>
|
||||||
<VcpkgEnabled>false</VcpkgEnabled>
|
<VcpkgEnabled>false</VcpkgEnabled>
|
||||||
<ReplaceWildcardsInProjectItems>true</ReplaceWildcardsInProjectItems>
|
<ReplaceWildcardsInProjectItems>true</ReplaceWildcardsInProjectItems>
|
||||||
<ExternalIncludePath>$(MSBuildThisFileFullPath)\..\deps\;$(MSBuildThisFileFullPath)\..\packages\;$(ExternalIncludePath)</ExternalIncludePath>
|
<ExternalIncludePath>$(MSBuildThisFileDirectory)deps;$(MSBuildThisFileDirectory)packages;$(ExternalIncludePath)</ExternalIncludePath>
|
||||||
<!-- Enable control flow guard for C++ projects that don't consume any C++ files -->
|
<!-- Enable control flow guard for C++ projects that don't consume any C++ files -->
|
||||||
<!-- This covers the case where a .dll exports a .lib, but doesn't have any ClCompile entries. -->
|
<!-- This covers the case where a .dll exports a .lib, but doesn't have any ClCompile entries. -->
|
||||||
<LinkControlFlowGuard>Guard</LinkControlFlowGuard>
|
<LinkControlFlowGuard>Guard</LinkControlFlowGuard>
|
||||||
|
|||||||
1
deps/cziplib
vendored
1
deps/cziplib
vendored
Submodule deps/cziplib deleted from 81314fff0a
@@ -30,6 +30,7 @@
|
|||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
<AdditionalIncludeDirectories>../../../src/</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../../src/</AdditionalIncludeDirectories>
|
||||||
|
<TreatAngleIncludeAsExternal>true</TreatAngleIncludeAsExternal>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@@ -37,10 +38,6 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\deps\cziplib\src\zip.c">
|
|
||||||
<!-- Disabling warnings for external code -->
|
|
||||||
<DisableSpecificWarnings>4706;26451;4267;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="EventViewer.cpp" />
|
<ClCompile Include="EventViewer.cpp" />
|
||||||
<ClCompile Include="InstallationFolder.cpp" />
|
<ClCompile Include="InstallationFolder.cpp" />
|
||||||
<ClCompile Include="Package.cpp" />
|
<ClCompile Include="Package.cpp" />
|
||||||
@@ -61,8 +58,6 @@
|
|||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\deps\cziplib\src\miniz.h" />
|
|
||||||
<ClInclude Include="..\..\..\deps\cziplib\src\zip.h" />
|
|
||||||
<ClInclude Include="EventViewer.h" />
|
<ClInclude Include="EventViewer.h" />
|
||||||
<ClInclude Include="InstallationFolder.h" />
|
<ClInclude Include="InstallationFolder.h" />
|
||||||
<ClInclude Include="Package.h" />
|
<ClInclude Include="Package.h" />
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
<ClCompile Include="ZipTools\ZipFolder.cpp">
|
<ClCompile Include="ZipTools\ZipFolder.cpp">
|
||||||
<Filter>ZipTools</Filter>
|
<Filter>ZipTools</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\..\deps\cziplib\src\zip.c" />
|
|
||||||
<ClCompile Include="ReportMonitorInfo.cpp" />
|
<ClCompile Include="ReportMonitorInfo.cpp" />
|
||||||
<ClCompile Include="RegistryUtils.cpp" />
|
<ClCompile Include="RegistryUtils.cpp" />
|
||||||
<ClCompile Include="EventViewer.cpp" />
|
<ClCompile Include="EventViewer.cpp" />
|
||||||
@@ -28,8 +27,6 @@
|
|||||||
<Filter>ZipTools</Filter>
|
<Filter>ZipTools</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\common\utils\json.h" />
|
<ClInclude Include="..\..\..\common\utils\json.h" />
|
||||||
<ClInclude Include="..\..\..\deps\cziplib\src\miniz.h" />
|
|
||||||
<ClInclude Include="..\..\..\deps\cziplib\src\zip.h" />
|
|
||||||
<ClInclude Include="ReportMonitorInfo.h" />
|
<ClInclude Include="ReportMonitorInfo.h" />
|
||||||
<ClInclude Include="RegistryUtils.h" />
|
<ClInclude Include="RegistryUtils.h" />
|
||||||
<ClInclude Include="EventViewer.h" />
|
<ClInclude Include="EventViewer.h" />
|
||||||
|
|||||||
@@ -1,50 +1,53 @@
|
|||||||
#include "ZipFolder.h"
|
#include "ZipFolder.h"
|
||||||
#include "..\..\..\..\deps\cziplib\src\zip.h"
|
|
||||||
#include <common/utils/timeutil.h>
|
#include <common/utils/timeutil.h>
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
#include <wil/stl.h>
|
||||||
|
#include <wil/win32_helpers.h>
|
||||||
|
|
||||||
void ZipFolder(std::filesystem::path zipPath, std::filesystem::path folderPath)
|
void ZipFolder(std::filesystem::path zipPath, std::filesystem::path folderPath)
|
||||||
{
|
{
|
||||||
std::string reportFilename{ "PowerToysReport_" };
|
const auto reportFilename{
|
||||||
reportFilename += timeutil::format_as_local("%F-%H-%M-%S", timeutil::now());
|
std::format("PowerToysReport_{0}.zip",
|
||||||
reportFilename += ".zip";
|
timeutil::format_as_local("%F-%H-%M-%S", timeutil::now()))
|
||||||
|
};
|
||||||
|
const auto finalReportFullPath{ zipPath / reportFilename };
|
||||||
|
|
||||||
auto tmpZipPath = std::filesystem::temp_directory_path();
|
const auto tempReportFilename{ reportFilename + ".tmp" };
|
||||||
tmpZipPath /= reportFilename;
|
const auto tempReportFullPath{ zipPath / tempReportFilename };
|
||||||
|
|
||||||
struct zip_t* zip = zip_open(tmpZipPath.string().c_str(), ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
// tar -c --format=zip -f "ReportFile.zip" *
|
||||||
if (!zip)
|
const auto executable{ wil::ExpandEnvironmentStringsW<std::wstring>(LR"(%WINDIR%\System32\tar.exe)") };
|
||||||
|
auto commandline{ std::format(LR"("{0}" -c --format=zip -f "{1}" *)", executable, tempReportFullPath.wstring()) };
|
||||||
|
|
||||||
|
const auto folderPathAsString{ folderPath.lexically_normal().wstring() };
|
||||||
|
|
||||||
|
wil::unique_process_information pi;
|
||||||
|
STARTUPINFOW si{ .cb = sizeof(STARTUPINFOW) };
|
||||||
|
if (!CreateProcessW(executable.c_str(),
|
||||||
|
commandline.data() /* must be mutable */,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
FALSE,
|
||||||
|
DETACHED_PROCESS,
|
||||||
|
nullptr,
|
||||||
|
folderPathAsString.c_str(),
|
||||||
|
&si,
|
||||||
|
&pi))
|
||||||
{
|
{
|
||||||
printf("Cannot open zip.");
|
printf("Cannot open zip.");
|
||||||
throw -1;
|
throw -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
using recursive_directory_iterator = std::filesystem::recursive_directory_iterator;
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
const size_t rootSize = folderPath.wstring().size();
|
|
||||||
for (const auto& dirEntry : recursive_directory_iterator(folderPath))
|
|
||||||
{
|
|
||||||
if (dirEntry.is_regular_file())
|
|
||||||
{
|
|
||||||
auto path = dirEntry.path().string();
|
|
||||||
auto relativePath = path.substr(rootSize, path.size());
|
|
||||||
zip_entry_open(zip, relativePath.c_str());
|
|
||||||
zip_entry_fwrite(zip, path.c_str());
|
|
||||||
zip_entry_close(zip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
zip_close(zip);
|
std::error_code err{};
|
||||||
|
std::filesystem::rename(tempReportFullPath, finalReportFullPath, err);
|
||||||
std::error_code err;
|
|
||||||
std::filesystem::copy(tmpZipPath, zipPath, err);
|
|
||||||
if (err.value() != 0)
|
if (err.value() != 0)
|
||||||
{
|
{
|
||||||
wprintf_s(L"Failed to copy %s. Error code: %d\n", tmpZipPath.c_str(), err.value());
|
wprintf_s(L"Failed to rename %s. Error code: %d\n", tempReportFullPath.native().c_str(), err.value());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
err = {};
|
|
||||||
std::filesystem::remove_all(tmpZipPath, err);
|
|
||||||
if (err.value() != 0)
|
|
||||||
{
|
|
||||||
wprintf_s(L"Failed to delete %s. Error code: %d\n", tmpZipPath.c_str(), err.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user