mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-05 08:02:11 +00:00
Add automated test for shell wildcard expansion
Wildcard expansion is different in Windows from non-Windows and sometimes requires special link options to work. Add tests that fail if we link incorrectly.
This commit is contained in:
parent
cfafac8d13
commit
deeface146
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@ -41,7 +41,6 @@ jobs:
|
|||||||
name: distribution
|
name: distribution
|
||||||
path: distribution
|
path: distribution
|
||||||
Windows:
|
Windows:
|
||||||
# If updating this, see note in TODO about MSVC wildcard expansion.
|
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
needs: Distfiles
|
needs: Distfiles
|
||||||
strategy:
|
strategy:
|
||||||
|
34
TODO
34
TODO
@ -4,8 +4,7 @@ Candidates for upcoming release
|
|||||||
* Easy build/test
|
* Easy build/test
|
||||||
* #460: potential malware in fuzzer seed corpus
|
* #460: potential malware in fuzzer seed corpus
|
||||||
* Consider building workflow on a schedule to detect build rot. This
|
* Consider building workflow on a schedule to detect build rot. This
|
||||||
may enable safe use of *-latest especially if Windows wildcard is
|
should enable safe use of *-latest on runners.
|
||||||
testable.
|
|
||||||
|
|
||||||
* Fuzz crashes
|
* Fuzz crashes
|
||||||
* See "New" below
|
* See "New" below
|
||||||
@ -29,9 +28,6 @@ Candidates for upcoming release
|
|||||||
because of changes in the build environment, library dependencies,
|
because of changes in the build environment, library dependencies,
|
||||||
compiler upgrades, etc.
|
compiler upgrades, etc.
|
||||||
|
|
||||||
* Find a way to deal with MSVC wildcard expansion, even if it requires
|
|
||||||
creating a separate step or adding code to build-windows.bat.
|
|
||||||
|
|
||||||
* See if we can work in Windows Build/External Libraries (below)
|
* See if we can work in Windows Build/External Libraries (below)
|
||||||
|
|
||||||
* Remember to check work `qpdf` project for private issues
|
* Remember to check work `qpdf` project for private issues
|
||||||
@ -220,34 +216,6 @@ Page splitting/merging
|
|||||||
|
|
||||||
* Form fields: should be similar to outlines.
|
* Form fields: should be similar to outlines.
|
||||||
|
|
||||||
MSVC Wildcard Expansion
|
|
||||||
=======================
|
|
||||||
|
|
||||||
(This section is referenced in azure_pipelines.yml and
|
|
||||||
.github/workflows/main.yml.)
|
|
||||||
|
|
||||||
The qpdf executable built with msvc is linked with setargv.obj or
|
|
||||||
wsetargv.obj so that wildcard expansion works. It doesn't work exactly
|
|
||||||
the way a UNIX system would work in that the program itself does the
|
|
||||||
expansion (rather than the shell), which means that invoking qpdf.exe
|
|
||||||
as built by msvc will expand "*.pdf" just as it will expand *.pdf. In
|
|
||||||
some earlier versions, wildcard expansion didn't work with the msvc
|
|
||||||
executable. The way to make this work appears to be different in some
|
|
||||||
versions of MSVC than in others. As such, if upgrading MSVC or
|
|
||||||
changing the build environment, the wildcard expansion behavior of the
|
|
||||||
qpdf executable in Windows should be retested manually.
|
|
||||||
|
|
||||||
Unfortunately, there is no automated test for wildcard expansion with
|
|
||||||
MSVC because I can't figure out how to prevent qtest from expanding
|
|
||||||
the wildcards before passing them in, and explicitly running "cmd /c
|
|
||||||
..." from qtest doesn't seem to work in Azure Pipelines (haven't
|
|
||||||
attempted in GitHub Actions), though I can make it work locally.
|
|
||||||
|
|
||||||
Ideally, we should figure out a way to test this in CI by having a
|
|
||||||
test that fails if wildcard expansion is broken. In the absence of
|
|
||||||
this, it will be necessary to test the behavior manually in both mingw
|
|
||||||
and msvc when run from cmd and from msys bash.
|
|
||||||
|
|
||||||
Performance
|
Performance
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ BINS_qpdf = \
|
|||||||
test_pdf_doc_encoding \
|
test_pdf_doc_encoding \
|
||||||
test_pdf_unicode \
|
test_pdf_unicode \
|
||||||
test_renumber \
|
test_renumber \
|
||||||
|
test_shell_glob \
|
||||||
test_tokenizer \
|
test_tokenizer \
|
||||||
test_unicode_filenames \
|
test_unicode_filenames \
|
||||||
test_xref
|
test_xref
|
||||||
@ -23,15 +24,14 @@ TC_SRCS_qpdf = $(wildcard libqpdf/*.cc) $(wildcard qpdf/*.cc)
|
|||||||
|
|
||||||
# -----
|
# -----
|
||||||
|
|
||||||
XCXXFLAGS_qpdf_qpdf := $(WINDOWS_WMAIN_COMPILE)
|
define use_wmain
|
||||||
XLDFLAGS_qpdf_qpdf := $(WINDOWS_WMAIN_LINK)
|
XCXXFLAGS_qpdf_$(1) := $(WINDOWS_WMAIN_COMPILE)
|
||||||
XLINK_FLAGS_qpdf_qpdf := $(WINDOWS_WMAIN_XLINK_FLAGS)
|
XLDFLAGS_qpdf_$(1) := $(WINDOWS_WMAIN_LINK)
|
||||||
XCXXFLAGS_qpdf_test_unicode_filenames := $(WINDOWS_WMAIN_COMPILE)
|
XLINK_FLAGS_qpdf_$(1) := $(WINDOWS_WMAIN_XLINK_FLAGS)
|
||||||
XLDFLAGS_qpdf_test_unicode_filenames := $(WINDOWS_WMAIN_LINK)
|
endef
|
||||||
XLINK_FLAGS_qpdf_test_unicode_filenames := $(WINDOWS_WMAIN_XLINK_FLAGS)
|
|
||||||
XCXXFLAGS_qpdf_fix-qdf := $(WINDOWS_WMAIN_COMPILE)
|
$(foreach B,qpdf test_unicode_filenames fix-qdf test_shell_glob,\
|
||||||
XLDFLAGS_qpdf_fix-qdf := $(WINDOWS_WMAIN_LINK)
|
$(eval $(call use_wmain,$(B))))
|
||||||
XLINK_FLAGS_qpdf_fix-qdf := $(WINDOWS_WMAIN_XLINK_FLAGS)
|
|
||||||
|
|
||||||
$(foreach B,$(BINS_qpdf),$(eval \
|
$(foreach B,$(BINS_qpdf),$(eval \
|
||||||
OBJS_$(B) = $(call src_to_obj,qpdf/$(B).cc)))
|
OBJS_$(B) = $(call src_to_obj,qpdf/$(B).cc)))
|
||||||
|
@ -189,6 +189,17 @@ foreach my $d (['auto-ü', 1], ['auto-öπ', 2])
|
|||||||
$td->NORMALIZE_NEWLINES);
|
$td->NORMALIZE_NEWLINES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
show_ntests();
|
||||||
|
# ----------
|
||||||
|
$td->notify("--- Windows shell globbing ---");
|
||||||
|
|
||||||
|
$td->runtest("shell wildcard expansion",
|
||||||
|
{$td->COMMAND => "test_shell_glob 'good*.pdf'"},
|
||||||
|
{$td->STRING => "PASSED\n", $td->EXIT_STATUS => 0},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
|
||||||
|
$n_tests += 1;
|
||||||
|
|
||||||
show_ntests();
|
show_ntests();
|
||||||
# ----------
|
# ----------
|
||||||
$td->notify("--- Replace Input ---");
|
$td->notify("--- Replace Input ---");
|
||||||
|
64
qpdf/test_shell_glob.cc
Normal file
64
qpdf/test_shell_glob.cc
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <cstring>
|
||||||
|
#include <qpdf/QUtil.hh>
|
||||||
|
|
||||||
|
int realmain(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
// In Windows, shell globbing is handled by the runtime, so
|
||||||
|
// passing '*' as argument results in wildcard expansion. In
|
||||||
|
// non-Windows, globbing is done by the shell, so passing '*'
|
||||||
|
// shows up as '*'. In Windows with MSVC, it is necessary to link
|
||||||
|
// a certain way for this to work. To test this, we invoke this
|
||||||
|
// program with a single quoted argument containing a shell glob
|
||||||
|
// expression. In Windows, we expect to see multiple arguments,
|
||||||
|
// none of which contain '*'. Otherwise, we expected to see the
|
||||||
|
// exact glob string that was passed in. The effectiveness of this
|
||||||
|
// test was exercised by manually breaking the link options for
|
||||||
|
// msvc and seeing that the test fails under that condition.
|
||||||
|
|
||||||
|
bool found_star = false;
|
||||||
|
for (int i = 1; i < argc; ++i)
|
||||||
|
{
|
||||||
|
if (strchr(argv[i], '*') != nullptr)
|
||||||
|
{
|
||||||
|
found_star = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
bool passed = ((! found_star) && (argc > 2));
|
||||||
|
#else
|
||||||
|
bool passed = (found_star && (argc == 2));
|
||||||
|
#endif
|
||||||
|
if (passed)
|
||||||
|
{
|
||||||
|
std::cout << "PASSED" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "FAILED" << std::endl;
|
||||||
|
for (int i = 1; i < argc; ++i)
|
||||||
|
{
|
||||||
|
std::cout << argv[i] << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WINDOWS_WMAIN
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int wmain(int argc, wchar_t* argv[])
|
||||||
|
{
|
||||||
|
return QUtil::call_main_from_wmain(argc, argv, realmain);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
return realmain(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user