summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorng0 <ng0@infotropique.org>2017-10-24 16:52:22 +0000
committerng0 <ng0@infotropique.org>2017-10-24 16:52:22 +0000
commit8252aa305004041b46e93e5f8b64dfee86ff78f8 (patch)
tree5bad91fb9964c0edb1cdf32db411c63ad937c13e
parentdc0683b6404f7204c2ad98fb77f92b00c0116525 (diff)
parentc514af5a4f5ac3ce724065cc6a8e009373436f78 (diff)
downloadgnurl-8252aa305004041b46e93e5f8b64dfee86ff78f8.tar.gz
gnurl-8252aa305004041b46e93e5f8b64dfee86ff78f8.tar.bz2
gnurl-8252aa305004041b46e93e5f8b64dfee86ff78f8.zip
Merge tag 'curl-7_56_1' of https://github.com/curl/curl
curl 7.56.1
-rw-r--r--.travis.yml19
-rw-r--r--CMakeLists.txt1
-rw-r--r--Makefile.am3
-rw-r--r--RELEASE-NOTES276
-rwxr-xr-xconfigure.ac7
-rw-r--r--docs/FAQ2
-rw-r--r--docs/HELP-US.md6
-rw-r--r--docs/RELEASE-PROCEDURE9
-rw-r--r--docs/THANKS8
-rw-r--r--docs/THANKS-filter1
-rw-r--r--docs/cmdline-opts/form.d9
-rw-r--r--docs/cmdline-opts/tlsv1.3.d3
-rw-r--r--docs/libcurl/gnurl_formadd.35
-rw-r--r--docs/libcurl/gnurl_mime_data_cb.32
-rw-r--r--docs/libcurl/gnurl_mime_filedata.36
-rw-r--r--docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.37
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_NOPROGRESS.310
-rw-r--r--docs/libcurl/opts/GNURLOPT_TIMEOUT.37
-rw-r--r--docs/libcurl/opts/GNURLOPT_XFERINFODATA.34
-rw-r--r--include/gnurl/curlver.h6
-rw-r--r--lib/Makefile.m3226
-rw-r--r--lib/config-os400.h10
-rw-r--r--lib/config-win32.h2
-rw-r--r--lib/formdata.c2
-rw-r--r--lib/ftp.c34
-rw-r--r--lib/http.c6
-rw-r--r--lib/imap.c5
-rw-r--r--lib/ldap.c4
-rw-r--r--lib/memdebug.c33
-rw-r--r--lib/memdebug.h10
-rw-r--r--lib/mime.c100
-rw-r--r--lib/mime.h2
-rwxr-xr-xlib/mk-ca-bundle.pl4
-rw-r--r--lib/multi.c52
-rw-r--r--lib/openldap.c4
-rw-r--r--lib/pingpong.c11
-rw-r--r--lib/sendf.c34
-rw-r--r--lib/smtp.c6
-rw-r--r--lib/strtoofft.c5
-rw-r--r--lib/url.c240
-rw-r--r--lib/urldata.h2
-rw-r--r--lib/vtls/axtls.c2
-rw-r--r--lib/vtls/cyassl.c2
-rw-r--r--lib/vtls/darwinssl.c94
-rw-r--r--lib/vtls/gskit.c2
-rw-r--r--lib/vtls/gtls.c2
-rw-r--r--lib/vtls/mbedtls.c2
-rw-r--r--lib/vtls/nss.c2
-rw-r--r--lib/vtls/openssl.c15
-rw-r--r--lib/vtls/polarssl.c2
-rw-r--r--lib/vtls/schannel.c2
-rw-r--r--lib/vtls/vtls.c20
-rw-r--r--lib/vtls/vtls.h2
-rw-r--r--packages/OS400/README.OS4003
-rw-r--r--packages/OS400/makefile.sh5
-rw-r--r--src/Makefile.m3213
-rw-r--r--src/tool_cb_hdr.c15
-rw-r--r--src/tool_formparse.c128
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/data/DISABLED2
-rw-r--r--tests/data/Makefile.inc11
-rw-r--r--tests/data/test14222
-rw-r--r--tests/data/test155252
-rw-r--r--tests/data/test155352
-rw-r--r--tests/data/test1737
-rw-r--r--tests/data/test2378
-rw-r--r--tests/data/test24454
-rw-r--r--tests/data/test2982
-rw-r--r--tests/data/test3081
-rw-r--r--tests/data/test5546
-rw-r--r--tests/data/test57755
-rw-r--r--tests/data/test5873
-rw-r--r--tests/data/test6441
-rw-r--r--tests/data/test6484
-rw-r--r--tests/data/test6509
-rw-r--r--tests/data/test65173
-rw-r--r--tests/data/test652358
-rw-r--r--tests/data/test65393
-rw-r--r--tests/data/test95043
-rwxr-xr-xtests/ftpserver.pl4
-rw-r--r--tests/fuzz/Makefile.am56
-rw-r--r--tests/fuzz/Makefile.inc15
-rw-r--r--tests/fuzz/README19
-rw-r--r--tests/fuzz/corpus.py96
-rw-r--r--tests/fuzz/curl_fuzz_data/oss-fuzz-3327bin27 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test1bin289 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test10bin226 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test100bin675 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test12bin464 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test13bin179 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test1326bin62 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test1450bin98 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test2bin182 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test271bin74 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test3bin242 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test4bin336 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test5bin185 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test6bin223 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test800bin137 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test850bin130 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzz_data/test900bin129 -> 0 bytes
-rw-r--r--tests/fuzz/curl_fuzzer.cc447
-rw-r--r--tests/fuzz/curl_fuzzer.h186
-rwxr-xr-xtests/fuzz/download_fuzzer.sh8
-rwxr-xr-xtests/fuzz/generate_corpus.py132
-rwxr-xr-xtests/fuzz/read_corpus.py69
-rw-r--r--tests/fuzz/standalone_fuzz_target_runner.cc89
-rw-r--r--tests/fuzz/testinput.h23
-rw-r--r--tests/libtest/Makefile.inc19
-rw-r--r--tests/libtest/lib1552.c93
-rw-r--r--tests/libtest/lib1553.c109
-rw-r--r--tests/libtest/lib554.c9
-rw-r--r--tests/libtest/lib643.c27
-rw-r--r--tests/libtest/lib650.c15
-rw-r--r--tests/libtest/lib651.c94
-rw-r--r--tests/libtest/lib652.c128
-rw-r--r--tests/libtest/lib653.c63
-rwxr-xr-xtests/memanalyze.pl30
-rwxr-xr-xtests/runtests.pl71
-rw-r--r--winbuild/BUILD.WINDOWS.txt1
121 files changed, 2306 insertions, 1633 deletions
diff --git a/.travis.yml b/.travis.yml
index 541628d99..b7776c98d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -156,18 +156,15 @@ script:
fi
- |
if [ "$T" = "fuzzer" ]; then
- export CC=clang
- export CXX=clang++
- export CFLAGS="-fsanitize=address"
+ # Download the fuzzer to a temporary folder
+ ./tests/fuzz/download_fuzzer.sh /tmp/curl_fuzzer
- # Specifically use libstdc++ for travis as libc++ is not installed.
- # This is ok because we're not compiling against libFuzzer.
- export CXXFLAGS="-fsanitize=address -stdlib=libstdc++"
- ./configure --disable-shared --enable-debug --enable-maintainer-mode
- make
- cd tests/fuzz
- make clean
- make check
+ export CURLSRC=$PWD
+
+ # Run the mainline fuzzer test
+ pushd /tmp/curl_fuzzer
+ ./mainline.sh ${CURLSRC}
+ popd
fi
# whitelist branches to avoid testing feature branches twice (as branch and as pull request)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5891c81d5..19099ff0a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -366,7 +366,6 @@ if(CMAKE_USE_OPENSSL)
check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
check_include_file("openssl/err.h" HAVE_OPENSSL_ERR_H)
check_include_file("openssl/pem.h" HAVE_OPENSSL_PEM_H)
- check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
check_include_file("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
check_include_file("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
check_include_file("openssl/x509.h" HAVE_OPENSSL_X509_H)
diff --git a/Makefile.am b/Makefile.am
index 2b5fcaea7..d668ead22 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -210,9 +210,6 @@ test-am:
endif
-fuzzer:
- @(cd tests/fuzz; $(MAKE) all)
-
examples:
@(cd docs/examples; $(MAKE) check)
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 971336faf..7da35d2eb 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,110 +1,63 @@
-Curl and libcurl 7.56.0
+Curl and libcurl 7.56.1
- Public curl releases: 169
+ Public curl releases: 170
Command line options: 211
curl_easy_setopt() options: 249
Public functions in libcurl: 74
- Contributors: 1618
-
-This release includes the following changes:
-
- o curl: enable compression for SCP/SFTP with --compressed-ssh [11]
- o libcurl: enable compression for SCP/SFTP with CURLOPT_SSH_COMPRESSION [11]
- o vtls: added dynamic changing SSL backend with curl_global_sslset() [28]
- o new MIME API, curl_mime_init() and friends [32]
- o openssl: initial SSLKEYLOGFILE implementation [36]
+ Contributors: 1626
This release includes the following bugfixes:
- o FTP: zero terminate the entry path even on bad input [67]
- o examples/ftpuploadresume.c: use portable code
- o runtests: match keywords case insensitively
- o travis: build the examples too [1]
- o strtoofft: reduce integer overflow risks globally [2]
- o zsh.pl: produce a working completion script again [3]
- o cmake: remove dead code for CURL_DISABLE_RTMP [4]
- o progress: Track total times following redirects [5]
- o configure: fix --disable-threaded-resolver [6]
- o cmake: remove dead code for DISABLED_THREADSAFE [7]
- o configure: fix clang version detection
- o darwinssi: fix error: variable length array used
- o travis: add metalink to some osx builds [8]
- o configure: check for __builtin_available() availability [9]
- o http_proxy: fix build error for CURL_DOES_CONVERSIONS [10]
- o examples/ftpuploadresume: checksrc compliance
- o ftp: fix CWD when doing multicwd then nocwd on same connection [12]
- o system.h: remove all CURL_SIZEOF_* defines [13]
- o http: Don't wait on CONNECT when there is no proxy [14]
- o system.h: check for __ppc__ as well [15]
- o http2_recv: return error better on fatal h2 errors [16]
- o scripts/contri*sh: use "git log --use-mailmap"
- o tftp: fix memory leak on too long filename [17]
- o system.h: fix build for hppa [18]
- o cmake: enable picky compiler options with clang and gcc [19]
- o makefile.m32: add support for libidn2 [20]
- o curl: turn off MinGW CRT's globbing [21]
- o request-target.d: mention added in 7.55.0
- o curl: shorten and clean up CA cert verification error message [22]
- o imap: support PREAUTH [23]
- o CURLOPT_USERPWD.3: see also CURLOPT_PROXYUSERPWD
- o examples/threaded-ssl: mention that this is for openssl before 1.1
- o winbuild: fix embedded manifest option [24]
- o tests: Make sure libtests & unittests call curl_global_cleanup()
- o system.h: include sys/poll.h for AIX [25]
- o darwinssl: handle long strings in TLS certs [26]
- o strtooff: fix build for systems with long long but no strtoll [27]
- o asyn-thread: Improved cleanup after OOM situations
- o HELP-US.md: "How to get started helping out in the curl project" [29]
- o curl.h: CURLSSLBACKEND_WOLFSSL used wrong value [30]
- o unit1301: fix error message on first test
- o ossfuzz: moving towards the ideal integration [31]
- o http: fix a memory leakage in checkrtspprefix()
- o examples/post-callback: stop returning one byte at a time
- o schannel: return CURLE_SSL_CACERT on failed verification [33]
- o MAIL-ETIQUETTE: added "1.9 Your emails are public"
- o http-proxy: treat all 2xx as CONNECT success [34]
- o openssl: use OpenSSL's default ciphers by default [35]
- o runtests.pl: support attribute "nonewline" in part verify/upload
- o configure: remove --enable-soname-bump and SONAME_BUMP [37]
- o travis: add c-ares enabled builds linux + osx [38]
- o vtls: fix WolfSSL 3.12 build problems [39]
- o http-proxy: when not doing CONNECT, that phase is done immediately [40]
- o configure: fix curl_off_t check's include order [41]
- o configure: use -Wno-varargs on clang 3.9[.X] debug builds
- o rtsp: do not call fwrite() with NULL pointer FILE * [42]
- o mbedtls: enable CA path processing [43]
- o travis: add build without HTTP/SMTP/IMAP
- o checksrc: verify more code style rules [44]
- o HTTP proxy: on connection re-use, still use the new remote port [45]
- o tests: add initial gssapi test using stub implementation [46]
- o rtsp: Segfault when using WRITEDATA [47]
- o docs: clarify the CURLOPT_INTERLEAVE* options behavior
- o non-ascii: use iconv() with 'char **' argument [48]
- o server/getpart: provide dummy function to build conversion enabled
- o conversions: fix several compiler warnings
- o openssl: add missing includes [49]
- o schannel: Support partial send for when data is too large [50]
- o socks: fix incorrect port number in SOCKS4 error message [51]
- o curl: fix integer overflow in timeout options [52]
- o travis: on mac, don't install openssl or libidn [53]
- o cookies: reject oversized cookies instead of truncating [54]
- o cookies: use lock when using CURLINFO_COOKIELIST [55]
- o curl: check fseek() return code and bail on error
- o examples/post-callback: use long for CURLOPT_POSTFIELDSIZE
- o openssl: only verify RSA private key if supported [56]
- o tests: make the imap server not verify user+password [57]
- o imap: quote atoms properly when escaping characters [58]
- o tests: fix a compiler warning in test 643
- o file_range: avoid integer overflow when figuring out byte range [59]
- o curl.h: include <sys/select.h> on cygwin too [60]
- o reuse_conn: don't copy flags that are known to be equal [61]
- o http: fix adding custom empty headers to repeated requests [62]
- o docs: clarify the use of environment variables for proxy [63]
- o docs: link CURLOPT_CONNECTTIMEOUT and CURLOPT_CONNECTTIMEOUT_MS [64]
- o connect: fix race condition with happy eyeballs timeout [65]
- o cookie: fix memory leak if path was set twice in header [66]
- o vtls: compare and clone ssl configs properly [68]
- o proxy: read the "no_proxy" variable only if necessary [69]
+ o imap: if a FETCH response has no size, don't call write callback [32]
+ o ftp: UBsan fixup 'pointer index expression overflowed [1]
+ o failf: skip the sprintf() if there are no consumers [2]
+ o fuzzer: move to using external curl-fuzzer [3]
+ o lib/Makefile.m32: allow customizing dll suffixes [4]
+ o docs: fix typo in curl_mime_data_cb man page [5]
+ o darwinssl: add support for TLSv1.3 [6]
+ o build: fix --disable-crypto-auth [7]
+ o lib/config-win32.h: let SMB/SMBS be enabled with OpenSSL/NSS [8]
+ o openssl: fix build without HAVE_OPAQUE_EVP_PKEY [9]
+ o strtoofft: Remove extraneous null check [10]
+ o multi_cleanup: call DONE on handles that never got that [11]
+ o tests: added flaky keyword to tests 587 and 644
+ o pingpong: return error when trying to send without connection [12]
+ o remove_handle: call multi_done() first, then clear dns cache pointer [13]
+ o mime: be tolerant about setting twice the same header list in a part.
+ o mime: improve unbinding top multipart from easy handle.
+ o mime: avoid resetting a part's encoder when part's contents change.
+ o mime: refuse to add subparts to one of their own descendants [14]
+ o RTSP: avoid integer overflow on funny RTSP responses [15]
+ o curl: don't pass semicolons when parsing Content-Disposition [16]
+ o openssl: enable PKCS12 support for !BoringSSL [17]
+ o FAQ: s/CURLOPT_PROGRESSFUNCTION/CURLOPT_XFERINFOFUNCTION
+ o CURLOPT_NOPROGRESS.3: also refer to xferinfofunction
+ o CURLOPT_XFERINFODATA.3: fix duplicate see also
+ o test298: verify --ftp-method nowcwd with URL encoded path [18]
+ o FTP: URL decode path for dir listing in nocwd mode [19]
+ o smtp_done: fix memory leak on send failure [20]
+ o ftpserver: support case insensitive commands
+ o test950; verify SMTP with custom request
+ o openssl: don't use old BORINGSSL_YYYYMM macros [21]
+ o setopt: update current connection SSL verify params [22]
+ o winbuild/BUILD.WINDOWS.txt: mention WITH_NGHTTP2
+ o curl: reimplement stdin buffering in -F option [23]
+ o mime: keep "text/plain" content type if user-specified [24]
+ o mime: fix the content reader to handle >16K data properly [25]
+ o configure: remove the C++ compiler check [26]
+ o memdebug: trace send, recv and socket [27]
+ o runtests: use valgrind for torture as well
+ o ldap: silence clang warning [28]
+ o makefile.m32: allow to override gcc, ar and ranlib [29]
+ o setopt: avoid integer overflows when setting millsecond values [30]
+ o setopt: range check most long options [31]
+ o ftp: reject illegal IP/port in PASV 227 response [33]
+ o mime: do not reuse previously computed multipart size [34]
+ o vtls: change struct Curl_ssl `close' field name to `close_one'
+ o os400: add missing symbols in config file
+ o mime: limit bas64-encoded lines length to 76 characters
+ o mk-ca-bundle: Remove URL for aurora [35]
+ o mk-ca-bundle: Fix URL for NSS [36]
This release includes the following known bugs:
@@ -113,89 +66,50 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and
advice from friends like these:
- Anders Bakken, Andrei Karas, Benbuck Nason, Ben Greear, Benjamin Sergeant,
- Bill Pyne, Brian Carpenter, Dan Fandrich, Daniel Stenberg, David Benjamin,
- Dirk Feytons, Even Rouault, Frank Denis, Gergely Nagy, Gisle Vanem,
- Ian Fette, imilli on github, Isaac Boukris, Jackarain on github,
- Jakub Zakrzewski, Jan Alexander Steffens, Johannes Schindelin,
- John David Anglin, joshhe on github, Kamil Dudka, Kevin Smith,
- Lawrence Wagerfield, Maksim Stsepanenka, Marc Aldorasi, Marcel Raad,
- Max Dymond, Michael Kaufmann, Michael Smith, Nick Zitzmann,
- Nicolas Morey-Chaisemartin, Oli Kingshott, Patrick Monnerat, Pavel P,
- Peter Lamare, Peter Wu, Ray Satiro, Rich Gray, Ryan Schmidt, Ryan Winograd,
- SBKarr on github, Tatsuhiro Tsujikawa, Viktor Szakáts,
- (47 contributors)
+ Alexey Melnichuk, Artak Galoyan, Benbuck Nason, Brian Carpenter,
+ Christian Schmitz, Dan Fandrich, Daniel Stenberg, David Benjamin,
+ Felix Kaiser, Javier Sixto, Jeroen Ooms, Jon DeVree, Kristiyan Tsaklev,
+ Marcel Raad, Max Dymond, Nick Zitzmann, Patrick Monnerat, Viktor Szakáts,
+ Wyatt O'Day, Zenju on github, 0xd34db347
+ (21 contributors)
Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues:
- [1] = https://curl.haxx.se/bug/?i=1777
- [2] = https://curl.haxx.se/bug/?i=1758
- [3] = https://curl.haxx.se/bug/?i=1779
- [4] = https://curl.haxx.se/bug/?i=1785
- [5] = https://curl.haxx.se/bug/?i=1602
- [6] = https://curl.haxx.se/bug/?i=1784
- [7] = https://curl.haxx.se/bug/?i=1786
- [8] = https://curl.haxx.se/bug/?i=1790
- [9] = https://curl.haxx.se/bug/?i=1788
- [10] = https://curl.haxx.se/bug/?i=1793
- [11] = https://curl.haxx.se/bug/?i=1735
- [12] = https://curl.haxx.se/bug/?i=1782
- [13] = https://curl.haxx.se/bug/?i=1767
- [14] = https://curl.haxx.se/bug/?i=1803
- [15] = https://curl.haxx.se/bug/?i=1797
- [16] = https://curl.haxx.se/bug/?i=1021
- [17] = https://curl.haxx.se/bug/?i=1808
- [18] = https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872502#10
- [19] = https://curl.haxx.se/bug/?i=1799
- [20] = https://curl.haxx.se/bug/?i=1815
- [21] = https://curl.haxx.se/bug/?i=1751
- [22] = https://curl.haxx.se/bug/?i=1810
- [23] = https://curl.haxx.se/bug/?i=1818
- [24] = https://curl.haxx.se/bug/?i=1832
- [25] = https://curl.haxx.se/bug/?i=1828
- [26] = https://curl.haxx.se/bug/?i=1823
- [27] = https://curl.haxx.se/bug/?i=1829
- [28] = https://curl.haxx.se/libcurl/c/curl_global_sslset.html
- [29] = https://curl.haxx.se/bug/?i=1837
- [30] = https://curl.haxx.se/mail/lib-2017-08/0120.html
- [31] = https://curl.haxx.se/bug/?i=1842
- [32] = https://curl.haxx.se/bug/?i=1839
- [33] = https://curl.haxx.se/bug/?i=1858
- [34] = https://curl.haxx.se/bug/?i=1859
- [35] = https://curl.haxx.se/bug/?i=1846
- [36] = https://curl.haxx.se/bug/?i=1866
- [37] = https://curl.haxx.se/bug/?i=1861
- [38] = https://curl.haxx.se/bug/?i=1868
- [39] = https://curl.haxx.se/bug/?i=1865
- [40] = https://curl.haxx.se/bug/?i=1853
- [41] = https://curl.haxx.se/bug/?i=1870
- [42] = https://curl.haxx.se/bug/?i=1874
- [43] = https://curl.haxx.se/bug/?i=1877
- [44] = https://curl.haxx.se/bug/?i=1878
- [45] = https://curl.haxx.se/bug/?i=1887
- [46] = https://curl.haxx.se/bug/?i=1687
- [47] = https://curl.haxx.se/bug/?i=1880
- [48] = https://curl.haxx.se/mail/lib-2017-09/0031.html
- [49] = https://curl.haxx.se/bug/?i=1891
- [50] = https://curl.haxx.se/bug/?i=1890
- [51] = https://curl.haxx.se/bug/?i=1892
- [52] = https://curl.haxx.se/bug/?i=1893
- [53] = https://curl.haxx.se/bug/?i=1895
- [54] = https://curl.haxx.se/bug/?i=1894
- [55] = https://curl.haxx.se/bug/?i=1896
- [56] = https://curl.haxx.se/bug/?i=1904
- [57] = https://curl.haxx.se/bug/?i=1902
- [58] = https://curl.haxx.se/bug/?i=1902
- [59] = https://curl.haxx.se/bug/?i=1908
- [60] = https://curl.haxx.se/bug/?i=1925
- [61] = https://curl.haxx.se/bug/?i=1918
- [62] = https://curl.haxx.se/bug/?i=1920
- [63] = https://curl.haxx.se/bug/?i=1921
- [64] = https://curl.haxx.se/bug/?i=1922
- [65] = https://curl.haxx.se/bug/?i=1928
- [66] = https://curl.haxx.se/bug/?i=1932
- [67] = https://curl.haxx.se/docs/adv_20171004.html
- [68] = https://curl.haxx.se/bug/?i=1917
- [69] = https://curl.haxx.se/bug/?i=1919
+ [1] = https://curl.haxx.se/bug/?i=1939
+ [2] = https://curl.haxx.se/bug/?i=1936
+ [3] = https://curl.haxx.se/bug/?i=1923
+ [4] = https://curl.haxx.se/bug/?i=1942
+ [5] = https://curl.haxx.se/bug/?i=1946
+ [6] = https://curl.haxx.se/bug/?i=1794
+ [7] = https://curl.haxx.se/bug/?i=1945
+ [8] = https://curl.haxx.se/bug/?i=1943
+ [9] = https://curl.haxx.se/bug/?i=1955
+ [10] = https://curl.haxx.se/bug/?i=1950
+ [11] = https://curl.haxx.se/bug/?i=1954
+ [12] = https://curl.haxx.se/bug/?i=1953
+ [13] = https://curl.haxx.se/bug/?i=1960
+ [14] = https://curl.haxx.se/bug/?i=1962
+ [15] = https://curl.haxx.se/bug/?i=1969
+ [16] = https://curl.haxx.se/bug/?i=1964
+ [17] = https://curl.haxx.se/bug/?i=1948
+ [18] = https://curl.haxx.se/bug/?i=1974
+ [19] = https://curl.haxx.se/bug/?i=1974
+ [20] = https://curl.haxx.se/bug/?i=1977
+ [21] = https://curl.haxx.se/bug/?i=1979
+ [22] = https://curl.haxx.se/bug/?i=1941
+ [23] = https://curl.haxx.se/bug/?i=1985
+ [24] = https://curl.haxx.se/bug/?i=1986
+ [25] = https://curl.haxx.se/bug/?i=1988
+ [26] = https://curl.haxx.se/bug/?i=1990
+ [27] = https://curl.haxx.se/bug/?i=1980
+ [28] = https://curl.haxx.se/bug/?i=1992
+ [29] = https://curl.haxx.se/bug/?i=1993
+ [30] = https://curl.haxx.se/bug/?i=1938
+ [31] = https://curl.haxx.se/bug/?i=1938
+ [32] = https://curl.haxx.se/docs/adv_20171023.html
+ [33] = https://curl.haxx.se/bug/?i=1997
+ [34] = https://curl.haxx.se/bug/?i=1999
+ [35] = https://curl.haxx.se/bug/?i=1998
+ [36] = https://curl.haxx.se/bug/?i=1998
diff --git a/configure.ac b/configure.ac
index 5424bc296..5d15aa8a6 100755
--- a/configure.ac
+++ b/configure.ac
@@ -124,7 +124,6 @@ AC_SUBST(libext)
dnl figure out the libcurl version
CURLVERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)".*/\1/p' ${srcdir}/include/gnurl/curlver.h`
XC_CHECK_PROG_CC
-AC_PROG_CXX
XC_AUTOMAKE
AC_MSG_CHECKING([curl version])
AC_MSG_RESULT($CURLVERSION)
@@ -1649,10 +1648,7 @@ if test -z "$ssl_backends" -o "x$OPT_SSL" != xno &&
fi
fi
- if test X"$OPENSSL_ENABLED" = X"1"; then
- dnl is there a pkcs12.h header present?
- AC_CHECK_HEADERS(openssl/pkcs12.h)
- else
+ if test X"$OPENSSL_ENABLED" != X"1"; then
LIBS="$CLEANLIBS"
fi
@@ -4056,7 +4052,6 @@ AC_CONFIG_FILES([Makefile \
tests/server/Makefile \
tests/libtest/Makefile \
tests/unit/Makefile \
- tests/fuzz/Makefile \
packages/Makefile \
packages/Win32/Makefile \
packages/Win32/cygwin/Makefile \
diff --git a/docs/FAQ b/docs/FAQ
index 5b9810637..7ed5fa0ce 100644
--- a/docs/FAQ
+++ b/docs/FAQ
@@ -1418,7 +1418,7 @@ FAQ
timed out.
The most flexible way is by writing your own time-out logic and using
- CURLOPT_PROGRESSFUNCTION (perhaps in combination with other callbacks) and
+ CURLOPT_XFERINFOFUNCTION (perhaps in combination with other callbacks) and
use that to figure out exactly when the right condition is met when the
transfer should get stopped.
diff --git a/docs/HELP-US.md b/docs/HELP-US.md
index d9e0bddc5..d37ad9480 100644
--- a/docs/HELP-US.md
+++ b/docs/HELP-US.md
@@ -17,9 +17,9 @@ down and report the bug. Or make your first pull request with a fix for that.
## PR-welcome
-In the issue tracker we occasionally mark bugs with
-[PR-welcome](https://github.com/curl/curl/labels/PR-welcome), as a sign that
-the bug is acknowledged to exist and that there's nobody known to work on this
+In the issue tracker we occasionally mark bugs with [help
+wanted](https://github.com/curl/curl/labels/help%20wanted), as a sign that the
+bug is acknowledged to exist and that there's nobody known to work on this
issue for the moment. Those are bugs that are fine to "grab" and provide a
pull request for. The complexity level of these will of course vary, so pick
one that piques your interest.
diff --git a/docs/RELEASE-PROCEDURE b/docs/RELEASE-PROCEDURE
index 5137f55d5..b7f8fcda0 100644
--- a/docs/RELEASE-PROCEDURE
+++ b/docs/RELEASE-PROCEDURE
@@ -83,10 +83,13 @@ Coming dates
Based on the description above, here are some planned release dates (at the
time of this writing):
-- June 14, 2017 (version 7.54.1)
-- August 9, 2017
-- October 4, 2017
- November 29, 2017
- January 24, 2018
- March 21, 2018
- May 16, 2018
+- July 11, 2018
+- September 5, 2018
+- October 31, 2018
+- December 26, 2018
+- February 20, 2019
+- April 17, 2019
diff --git a/docs/THANKS b/docs/THANKS
index 5aa2a122c..14a131938 100644
--- a/docs/THANKS
+++ b/docs/THANKS
@@ -60,6 +60,7 @@ Alexander Sinditskiy
Alexander Traud
Alexander Zhuravlev
Alexey Borzov
+Alexey Melnichuk
Alexey Pesternikov
Alexey Simak
Alexey Zakhlestin
@@ -131,6 +132,7 @@ Arkadiusz Miskiewicz
Armel Asselin
Arnaud Compan
Arnaud Ebalard
+Artak Galoyan
Arthur Murray
Arve Knudsen
Arvid Norberg
@@ -481,6 +483,7 @@ Fabrizio Ammollo
Fahim Chandurwala
Fedor Karpelevitch
Feist Josselin
+Felix Kaiser
Felix Yan
Felix von Leitner
Feng Tu
@@ -664,6 +667,7 @@ Jason McDonald
Jason S. Priebe
Javier Barroso
Javier G. Sogo
+Javier Sixto
Jay Austin
Jayesh A Shah
Jaz Fresh
@@ -750,6 +754,7 @@ John Wanghui
John Wilkinson
John-Mark Bell
Johnny Luong
+Jon DeVree
Jon Grubbs
Jon Nelson
Jon Sargeant
@@ -842,6 +847,7 @@ Krishnendu Majumdar
Krister Johansen
Kristian Gunstone
Kristian Köhntopp
+Kristiyan Tsaklev
Kurt Fankhauser
Kyle J. McKay
Kyle L. Huff
@@ -1561,6 +1567,7 @@ William Ahern
Wojciech Zwiefka
Wouter Van Rooy
Wu Yongzheng
+Wyatt O'Day
Xavier Bouchoux
Xiangbin Li
Yaakov Selkowitz
@@ -1581,6 +1588,7 @@ Yves Arrouye
Yves Lejeune
Zdenek Pavlas
Zekun Ni
+Zenju on github
Zmey Petroff
Zvi Har'El
afrind on github
diff --git a/docs/THANKS-filter b/docs/THANKS-filter
index 3ff912214..4c447be68 100644
--- a/docs/THANKS-filter
+++ b/docs/THANKS-filter
@@ -76,3 +76,4 @@ s/ERAMOTO Masaya$/Eramoto Masaya/
s/shachaf on github$/Shachaf Ben-Kiki/
s/CarloCannas on github$/Carlo Cannas/
s/Henrik S. Gaßmann$/Henrik Gaßmann/
+s/moteus on github/Alexey Melnichuk/
diff --git a/docs/cmdline-opts/form.d b/docs/cmdline-opts/form.d
index 232d30c07..b3251bdb8 100644
--- a/docs/cmdline-opts/form.d
+++ b/docs/cmdline-opts/form.d
@@ -25,9 +25,12 @@ the form-field to which portrait.jpg will be the input:
curl -F profile=@portrait.jpg https://example.com/upload.cgi
To read content from stdin instead of a file, use - as the filename. This goes
-for both @ and < constructs. Unfortunately it does not support reading the
-file from a named pipe or similar, as it needs the full size before the
-transfer starts.
+for both @ and < constructs. If stdin is not attached to a regular file, it is
+buffered first to determine its size and allow a possible resend. Defining a
+part's data from a named non-regular file (such as a named pipe or similar) is
+unfortunately not subject to buffering and will be effectively read at
+transmission time; since the full size is unknown before the transfer starts,
+data is sent as chunks by HTTP and rejected by IMAP.
You can also tell curl what Content-Type to use by using 'type=', in a manner
similar to:
diff --git a/docs/cmdline-opts/tlsv1.3.d b/docs/cmdline-opts/tlsv1.3.d
index 7d9640e71..123589653 100644
--- a/docs/cmdline-opts/tlsv1.3.d
+++ b/docs/cmdline-opts/tlsv1.3.d
@@ -6,4 +6,5 @@ Added: 7.52.0
Forces curl to use TLS version 1.3 when connecting to a remote TLS server.
Note that TLS 1.3 is only supported by a subset of TLS backends. At the time
-of writing this, those are BoringSSL and NSS only.
+of this writing, they are BoringSSL, NSS, and Secure Transport (on iOS 11 or
+later, and macOS 10.13 or later).
diff --git a/docs/libcurl/gnurl_formadd.3 b/docs/libcurl/gnurl_formadd.3
index 12604f1ae..b1215eae1 100644
--- a/docs/libcurl/gnurl_formadd.3
+++ b/docs/libcurl/gnurl_formadd.3
@@ -172,7 +172,10 @@ you've called \fIcurl_easy_cleanup(3)\fP for the curl handle.
See example below.
.SH AVAILABILITY
Deprecated in 7.56.0. Before this release, field names were allowed to
-contain zero-valued bytes.
+contain zero-valued bytes. The pseudo-filename "-" to read stdin is
+discouraged although still supported, but data is not read before being
+actually sent: the effective data size can then not be automatically
+determined, resulting in a chunked encoding transfer.
.SH RETURN VALUE
0 means everything was ok, non-zero means an error occurred corresponding
to a CURL_FORMADD_* constant defined in
diff --git a/docs/libcurl/gnurl_mime_data_cb.3 b/docs/libcurl/gnurl_mime_data_cb.3
index bc74a85a5..f8421d5da 100644
--- a/docs/libcurl/gnurl_mime_data_cb.3
+++ b/docs/libcurl/gnurl_mime_data_cb.3
@@ -31,7 +31,7 @@ int seekfunc(void *arg, curl_off_t offset, int origin);
.br
void freefunc(void *arg);
.sp
-.BI "CURLcode curl_mime_data(curl_mimepart * " part ", curl_off_t " datasize ,
+.BI "CURLcode curl_mime_data_cb(curl_mimepart * " part ", curl_off_t " datasize ,
.br
.BI " curl_read_callback " readfunc ", curl_seek_callback " seekfunc ,
.br
diff --git a/docs/libcurl/gnurl_mime_filedata.3 b/docs/libcurl/gnurl_mime_filedata.3
index 9a57068de..f522d997f 100644
--- a/docs/libcurl/gnurl_mime_filedata.3
+++ b/docs/libcurl/gnurl_mime_filedata.3
@@ -36,7 +36,7 @@ data to a mime part.
\fIpart\fP is the part's to assign contents to.
\fIfilename\fP points to the nul-terminated file's path name. The pointer can
-be NULL to detach previous part contents settings. Filename storage can be
+be NULL to detach the previous part contents settings. Filename storage can be
safely be reused after this call.
As a side effect, the part's remote file name is set to the base name of the
@@ -47,6 +47,10 @@ The contents of the file is read during the file transfer in a streaming
manner to allow huge files to get transfered without using much memory. It
therefore requires that the file is kept intact during the entire request.
+If the file size cannot be determined before actually reading it (such as for
+a device or named pipe), the whole mime structure containing the part
+will be transferred as chunks by HTTP and rejected by IMAP.
+
Setting a part's contents twice is valid: only the value set by the last call
is retained.
.SH AVAILABILITY
diff --git a/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.3 b/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.3
index 3e3dca396..195566fd3 100644
--- a/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.3
+++ b/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -58,7 +58,8 @@ if(curl) {
.SH AVAILABILITY
Always
.SH RETURN VALUE
-Returns CURLE_OK
+Returns CURLE_OK. Returns CURLE_BAD_FUNCTION_ARGUMENT if set to a negative
+value or a value that when converted to milliseconds is too large.
.SH "SEE ALSO"
-.BR CURLOPT_CONNECTTIMEOUT_MS "(3), "
+.BR CURLOPT_CONNECTTIMEOUT_MS "(3), "
.BR CURLOPT_TIMEOUT "(3), " CURLOPT_LOW_SPEED_LIMIT "(3), "
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.3 b/docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.3
index deee026c5..1d8b6dff9 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.3
@@ -54,7 +54,9 @@ if(curl) {
.SH AVAILABILITY
Added in 7.10.8
.SH RETURN VALUE
-Returns CURLE_OK if FTP is supported, and CURLE_UNKNOWN_OPTION if not.
+Returns CURLE_OK if FTP is supported, and CURLE_UNKNOWN_OPTION if not. Returns
+CURLE_BAD_FUNCTION_ARGUMENT if set to a negative value or a value that when
+converted to milliseconds is too large.
.SH "SEE ALSO"
.BR CURLOPT_TIMEOUT "(3), " CURLOPT_CONNECTTIMEOUT "(3), "
.BR CURLOPT_LOW_SPEED_LIMIT "(3), "
diff --git a/docs/libcurl/opts/GNURLOPT_NOPROGRESS.3 b/docs/libcurl/opts/GNURLOPT_NOPROGRESS.3
index 513ad6c31..0d1a1c7c7 100644
--- a/docs/libcurl/opts/GNURLOPT_NOPROGRESS.3
+++ b/docs/libcurl/opts/GNURLOPT_NOPROGRESS.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -30,10 +30,8 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_NOPROGRESS, long onoff);
.SH DESCRIPTION
If \fIonoff\fP is to 1, it tells the library to shut off the progress meter
completely for requests done with this \fIhandle\fP. It will also prevent the
-\fICURLOPT_PROGRESSFUNCTION(3)\fP from getting called.
-
-Future versions of libcurl are likely to not have any built-in progress meter
-at all.
+\fICURLOPT_XFERINFOFUNCTION(3)\fP or \fICURLOPT_PROGRESSFUNCTION(3)\fP from
+getting called.
.SH DEFAULT
1, meaning it normally runs without a progress meter.
.SH PROTOCOLS
@@ -56,4 +54,6 @@ Always
.SH RETURN VALUE
Returns CURLE_OK.
.SH "SEE ALSO"
+.BR CURLOPT_XFERINFOFUNCTION "(3), "
.BR CURLOPT_PROGRESSFUNCTION "(3), "
+.BR CURLOPT_VERBOSE "(3), "
diff --git a/docs/libcurl/opts/GNURLOPT_TIMEOUT.3 b/docs/libcurl/opts/GNURLOPT_TIMEOUT.3
index d9e61309d..b645cde6d 100644
--- a/docs/libcurl/opts/GNURLOPT_TIMEOUT.3
+++ b/docs/libcurl/opts/GNURLOPT_TIMEOUT.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -64,7 +64,8 @@ if(curl) {
.SH AVAILABILITY
Always
.SH RETURN VALUE
-Returns CURLE_OK
+Returns CURLE_OK. Returns CURLE_BAD_FUNCTION_ARGUMENT if set to a negative
+value or a value that when converted to milliseconds is too large.
.SH "SEE ALSO"
-.BR CURLOPT_TIMEOUT_MS "(3), "
+.BR CURLOPT_TIMEOUT_MS "(3), "
.BR CURLOPT_CONNECTTIMEOUT "(3), " CURLOPT_LOW_SPEED_LIMIT "(3), "
diff --git a/docs/libcurl/opts/GNURLOPT_XFERINFODATA.3 b/docs/libcurl/opts/GNURLOPT_XFERINFODATA.3
index 887d82062..c7281c781 100644
--- a/docs/libcurl/opts/GNURLOPT_XFERINFODATA.3
+++ b/docs/libcurl/opts/GNURLOPT_XFERINFODATA.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -43,4 +43,4 @@ Added in 7.32.0
.SH RETURN VALUE
Returns CURLE_OK
.SH "SEE ALSO"
-.BR CURLOPT_XFERINFOFUNCTION "(3), " CURLOPT_XFERINFOFUNCTION "(3), "
+.BR CURLOPT_XFERINFOFUNCTION "(3), " CURLOPT_VERBOSE "(3), "
diff --git a/include/gnurl/curlver.h b/include/gnurl/curlver.h
index 8c9fb5e3a..eff1148f1 100644
--- a/include/gnurl/curlver.h
+++ b/include/gnurl/curlver.h
@@ -30,12 +30,12 @@
/* This is the version number of the libcurl package from which this header
file origins: */
-#define LIBCURL_VERSION "7.56.0-DEV"
+#define LIBCURL_VERSION "7.57.0-DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 56
+#define LIBCURL_VERSION_MINOR 57
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
@@ -57,7 +57,7 @@
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
-#define LIBCURL_VERSION_NUM 0x073800
+#define LIBCURL_VERSION_NUM 0x073900
/*
* This is the date and time when the full source package was created. The
diff --git a/lib/Makefile.m32 b/lib/Makefile.m32
index 22efbdee0..1389b8539 100644
--- a/lib/Makefile.m32
+++ b/lib/Makefile.m32
@@ -22,7 +22,7 @@
###########################################################################
#
-## Makefile for building libcurl.a with MingW (GCC-3.2 or later)
+## Makefile for building libcurl.a with MingW (GCC-3.2 or later or LLVM/Clang)
## and optionally OpenSSL (1.0.2a), libssh2 (1.5), zlib (1.2.8), librtmp (2.4)
##
## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
@@ -76,13 +76,23 @@ ifndef LIBCARES_PATH
LIBCARES_PATH = $(PROOT)/ares
endif
-CC = $(CROSSPREFIX)gcc
+ifeq ($(CURL_CC),)
+CURL_CC := $(CROSSPREFIX)gcc
+endif
+ifeq ($(CURL_AR),)
+CURL_AR := $(CROSSPREFIX)ar
+endif
+ifeq ($(CURL_RANLIB),)
+CURL_RANLIB := $(CROSSPREFIX)ranlib
+endif
+
+CC = $(CURL_CC)
CFLAGS = $(CURL_CFLAG_EXTRAS) -g -O2 -Wall -W
CFLAGS += -fno-strict-aliasing
# comment LDFLAGS below to keep debug info
LDFLAGS = $(CURL_LDFLAG_EXTRAS) $(CURL_LDFLAG_EXTRAS_DLL) -s
-AR = $(CROSSPREFIX)ar
-RANLIB = $(CROSSPREFIX)ranlib
+AR = $(CURL_AR)
+RANLIB = $(CURL_RANLIB)
RC = $(CROSSPREFIX)windres
RCFLAGS = --include-dir=$(PROOT)/include -DDEBUGBUILD=0 -O COFF
STRIP = $(CROSSPREFIX)strip -g
@@ -313,8 +323,12 @@ DLL_LIBS += -lws2_32
# Makefile.inc provides the CSOURCES and HHEADERS defines
include Makefile.inc
-libcurl_dll_LIBRARY = libcurl.dll
-libcurl_dll_a_LIBRARY = libcurldll.a
+ifeq ($(CURL_DLL_A_SUFFIX),)
+CURL_DLL_A_SUFFIX := dll
+endif
+
+libcurl_dll_LIBRARY = libcurl$(CURL_DLL_SUFFIX).dll
+libcurl_dll_a_LIBRARY = libcurl$(CURL_DLL_A_SUFFIX).a
libcurl_a_LIBRARY = libcurl.a
libcurl_a_OBJECTS := $(patsubst %.c,%.o,$(strip $(CSOURCES)))
diff --git a/lib/config-os400.h b/lib/config-os400.h
index fe5b864d6..7844444fe 100644
--- a/lib/config-os400.h
+++ b/lib/config-os400.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -403,8 +403,14 @@
/* The size of `short', as computed by sizeof. */
#define SIZEOF_SHORT 2
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
/* The size of `size_t', as computed by sizeof. */
-#define SIZEOF_SIZE_T 8
+#define SIZEOF_SIZE_T 4
+
+/* The size of `curl_off_t', as computed by sizeof. */
+#define SIZEOF_CURL_OFF_T 8
/* Whether long long constants must be suffixed by LL. */
diff --git a/lib/config-win32.h b/lib/config-win32.h
index 00191fe4c..309f701a9 100644
--- a/lib/config-win32.h
+++ b/lib/config-win32.h
@@ -709,9 +709,7 @@ Vista
#endif
/* Define to use the Windows crypto library. */
-#if !defined(USE_OPENSSL) && !defined(USE_NSS)
#define USE_WIN32_CRYPTO
-#endif
/* ---------------------------------------------------------------- */
/* ADDITIONAL DEFINITIONS */
diff --git a/lib/formdata.c b/lib/formdata.c
index 1037d0ec8..429031354 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -906,7 +906,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
result = curl_mime_headers(part, file->contentheader, 0);
/* Set the content type. */
- if(!result &&file->contenttype)
+ if(!result && file->contenttype)
result = curl_mime_type(part, file->contenttype);
/* Set field name. */
diff --git a/lib/ftp.c b/lib/ftp.c
index 8590576f0..0141a0dca 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1457,25 +1457,22 @@ static CURLcode ftp_state_list(struct connectdata *conn)
then just do LIST (in that case: nothing to do here)
*/
char *cmd, *lstArg, *slashPos;
+ const char *inpath = data->state.path;
lstArg = NULL;
if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
- data->state.path &&
- data->state.path[0] &&
- strchr(data->state.path, '/')) {
-
- lstArg = strdup(data->state.path);
- if(!lstArg)
- return CURLE_OUT_OF_MEMORY;
+ inpath && inpath[0] && strchr(inpath, '/')) {
+ size_t n = strlen(inpath);
/* Check if path does not end with /, as then we cut off the file part */
- if(lstArg[strlen(lstArg) - 1] != '/') {
-
+ if(inpath[n - 1] != '/') {
/* chop off the file part if format is dir/dir/file */
- slashPos = strrchr(lstArg, '/');
- if(slashPos)
- *(slashPos + 1) = '\0';
+ slashPos = strrchr(inpath, '/');
+ n = slashPos - inpath;
}
+ result = Curl_urldecode(data, inpath, n, &lstArg, NULL, FALSE);
+ if(result)
+ return result;
}
cmd = aprintf("%s%s%s",
@@ -1877,8 +1874,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
else if((ftpc->count1 == 1) &&
(ftpcode == 227)) {
/* positive PASV response */
- int ip[4];
- int port[2];
+ unsigned int ip[4];
+ unsigned int port[2];
/*
* Scan for a sequence of six comma-separated numbers and use them as
@@ -1890,14 +1887,15 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
* "227 Entering passive mode. 127,0,0,1,4,51"
*/
while(*str) {
- if(6 == sscanf(str, "%d,%d,%d,%d,%d,%d",
+ if(6 == sscanf(str, "%u,%u,%u,%u,%u,%u",
&ip[0], &ip[1], &ip[2], &ip[3],
&port[0], &port[1]))
break;
str++;
}
- if(!*str) {
+ if(!*str || (ip[0] > 255) || (ip[1] > 255) || (ip[2] > 255) ||
+ (ip[3] > 255) || (port[0] > 255) || (port[1] > 255) ) {
failf(data, "Couldn't interpret the 227-response");
return CURLE_FTP_WEIRD_227_FORMAT;
}
@@ -2419,8 +2417,8 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
char *bytes;
char *buf = data->state.buffer;
bytes = strstr(buf, " bytes");
- if(bytes--) {
- long in = (long)(bytes-buf);
+ if(bytes) {
+ long in = (long)(--bytes-buf);
/* this is a hint there is size information in there! ;-) */
while(--in) {
/* scan for the left parenthesis and break there */
diff --git a/lib/http.c b/lib/http.c
index 962909055..52f4c2b65 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -3387,12 +3387,14 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
}
else if(conn->handler->protocol & CURLPROTO_RTSP) {
+ char separator;
nc = sscanf(HEADER1,
- " RTSP/%d.%d %3d",
+ " RTSP/%1d.%1d%c%3d",
&rtspversion_major,
&conn->rtspversion,
+ &separator,
&k->httpcode);
- if(nc == 3) {
+ if((nc == 4) && (' ' == separator)) {
conn->rtspversion += 10 * rtspversion_major;
conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
}
diff --git a/lib/imap.c b/lib/imap.c
index 9cf2bf86a..c059ff90c 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1126,6 +1126,11 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
/* The conversion from curl_off_t to size_t is always fine here */
chunk = (size_t)size;
+ if(!chunk) {
+ /* no size, we're done with the data */
+ state(conn, IMAP_STOP);
+ return CURLE_OK;
+ }
result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk);
if(result)
return result;
diff --git a/lib/ldap.c b/lib/ldap.c
index 4059d5d87..7f4f4dd76 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -190,9 +190,11 @@ static int ldap_win_bind_auth(LDAP *server, const char *user,
const char *passwd, unsigned long authflags)
{
ULONG method = 0;
- SEC_WINNT_AUTH_IDENTITY cred = { 0, };
+ SEC_WINNT_AUTH_IDENTITY cred;
int rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
+ memset(&cred, 0, sizeof(cred));
+
#if defined(USE_SPNEGO)
if(authflags & CURLAUTH_NEGOTIATE) {
method = LDAP_AUTH_NEGOTIATE;
diff --git a/lib/memdebug.c b/lib/memdebug.c
index c12910ef6..c21fab59b 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -343,7 +343,12 @@ curl_socket_t curl_socket(int domain, int type, int protocol,
"FD %s:%d socket() = %ld\n" :
"FD %s:%d socket() = %zd\n";
- curl_socket_t sockfd = socket(domain, type, protocol);
+ curl_socket_t sockfd;
+
+ if(countcheck("socket", line, source))
+ return CURL_SOCKET_BAD;
+
+ sockfd = socket(domain, type, protocol);
if(source && (sockfd != CURL_SOCKET_BAD))
curl_memlog(fmt, source, line, sockfd);
@@ -351,6 +356,32 @@ curl_socket_t curl_socket(int domain, int type, int protocol,
return sockfd;
}
+ssize_t curl_dosend(int sockfd, const void *buf, size_t len, int flags,
+ int line, const char *source)
+{
+ ssize_t rc;
+ if(countcheck("send", line, source))
+ return -1;
+ rc = send(sockfd, buf, len, flags);
+ if(source)
+ curl_memlog("SEND %s:%d send(%zu) = %zd\n",
+ source, line, len, rc);
+ return rc;
+}
+
+ssize_t curl_dorecv(int sockfd, void *buf, size_t len, int flags,
+ int line, const char *source)
+{
+ ssize_t rc;
+ if(countcheck("recv", line, source))
+ return -1;
+ rc = recv(sockfd, buf, len, flags);
+ if(source)
+ curl_memlog("RECV %s:%d recv(%zu) = %zd\n",
+ source, line, len, rc);
+ return rc;
+}
+
#ifdef HAVE_SOCKETPAIR
int curl_socketpair(int domain, int type, int protocol,
curl_socket_t socket_vector[2],
diff --git a/lib/memdebug.h b/lib/memdebug.h
index 835dab38c..c6b9225f4 100644
--- a/lib/memdebug.h
+++ b/lib/memdebug.h
@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -66,6 +66,12 @@ CURL_EXTERN int curl_socketpair(int domain, int type, int protocol,
int line, const char *source);
#endif
+/* send/receive sockets */
+CURL_EXTERN ssize_t curl_dosend(int sockfd, const void *buf, size_t len,
+ int flags, int line, const char *source);
+CURL_EXTERN ssize_t curl_dorecv(int sockfd, void *buf, size_t len, int flags,
+ int line, const char *source);
+
/* FILE functions */
CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line,
const char *source);
@@ -84,6 +90,8 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__)
#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)
#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__)
+#define send(a,b,c,d) curl_dosend(a,b,c,d, __LINE__, __FILE__)
+#define recv(a,b,c,d) curl_dorecv(a,b,c,d, __LINE__, __FILE__)
#ifdef WIN32
# ifdef UNICODE
diff --git a/lib/mime.c b/lib/mime.c
index 0aa12d1eb..8f67a1fca 100644
--- a/lib/mime.c
+++ b/lib/mime.c
@@ -26,6 +26,8 @@
#include "mime.h"
#include "non-ascii.h"
+#include "urldata.h"
+#include "sendf.h"
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \
!defined(CURL_DISABLE_IMAP)
@@ -404,7 +406,7 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
while(st->bufbeg < st->bufend) {
/* Line full ? */
- if(st->pos >= MAX_ENCODED_LINE_LENGTH - 4) {
+ if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) {
/* Yes, we need 2 characters for CRLF. */
if(size < 2)
break;
@@ -419,7 +421,7 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
if(size < 4 || st->bufend - st->bufbeg < 3)
break;
- /* Encode three bytes a four characters. */
+ /* Encode three bytes as four characters. */
i = st->buf[st->bufbeg++] & 0xFF;
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
@@ -618,14 +620,13 @@ static size_t mime_mem_read(char *buffer, size_t size, size_t nitems,
{
curl_mimepart *part = (curl_mimepart *) instream;
size_t sz = (size_t) part->datasize - part->state.offset;
-
(void) size; /* Always 1.*/
if(sz > nitems)
sz = nitems;
if(sz)
- memcpy(buffer, (char *) part->data, sz);
+ memcpy(buffer, (char *) &part->data[part->state.offset], sz);
part->state.offset += sz;
return sz;
@@ -1069,13 +1070,6 @@ static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
return result;
}
-static void mime_subparts_free(void *ptr)
-{
- curl_mime *mime = (curl_mime *) ptr;
- curl_mime_free(mime);
-}
-
-
/* Release part content. */
static void cleanup_part_content(curl_mimepart *part)
{
@@ -1089,11 +1083,34 @@ static void cleanup_part_content(curl_mimepart *part)
part->data = NULL;
part->fp = NULL;
part->datasize = (curl_off_t) 0; /* No size yet. */
- part->encoder = NULL;
cleanup_encoder_state(&part->encstate);
part->kind = MIMEKIND_NONE;
}
+static void mime_subparts_free(void *ptr)
+{
+ curl_mime *mime = (curl_mime *) ptr;
+
+ if(mime && mime->parent) {
+ mime->parent->freefunc = NULL; /* Be sure we won't be called again. */
+ cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */
+ }
+ curl_mime_free(mime);
+}
+
+/* Do not free subparts: unbind them. This is used for the top level only. */
+static void mime_subparts_unbind(void *ptr)
+{
+ curl_mime *mime = (curl_mime *) ptr;
+
+ if(mime && mime->parent) {
+ mime->parent->freefunc = NULL; /* Be sure we won't be called again. */
+ cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */
+ mime->parent = NULL;
+ }
+}
+
+
void Curl_mime_cleanpart(curl_mimepart *part)
{
cleanup_part_content(part);
@@ -1112,6 +1129,7 @@ void curl_mime_free(curl_mime *mime)
curl_mimepart *part;
if(mime) {
+ mime_subparts_unbind(mime); /* Be sure it's not referenced anymore. */
while(mime->firstpart) {
part = mime->firstpart;
mime->firstpart = part->nextpart;
@@ -1356,7 +1374,8 @@ CURLcode curl_mime_headers(curl_mimepart *part,
return CURLE_BAD_FUNCTION_ARGUMENT;
if(part->flags & MIME_USERHEADERS_OWNER) {
- curl_slist_free_all(part->userheaders);
+ if(part->userheaders != headers) /* Allow setting twice the same list. */
+ curl_slist_free_all(part->userheaders);
part->flags &= ~MIME_USERHEADERS_OWNER;
}
part->userheaders = headers;
@@ -1389,9 +1408,11 @@ CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize,
}
/* Set mime part content from subparts. */
-CURLcode curl_mime_subparts(curl_mimepart *part,
- curl_mime *subparts)
+CURLcode Curl_mime_set_subparts(curl_mimepart *part,
+ curl_mime *subparts, int take_ownership)
{
+ curl_mime *root;
+
if(!part)
return CURLE_BAD_FUNCTION_ARGUMENT;
@@ -1410,10 +1431,22 @@ CURLcode curl_mime_subparts(curl_mimepart *part,
if(subparts->parent)
return CURLE_BAD_FUNCTION_ARGUMENT;
+ /* Should not be the part's root. */
+ root = part->parent;
+ if(root) {
+ while(root->parent && root->parent->parent)
+ root = root->parent->parent;
+ if(subparts == root) {
+ if(part->easy)
+ failf(part->easy, "Can't add itself as a subpart!");
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+ }
+
subparts->parent = part;
part->readfunc = mime_subparts_read;
part->seekfunc = mime_subparts_seek;
- part->freefunc = mime_subparts_free;
+ part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind;
part->arg = subparts;
part->datasize = -1;
part->kind = MIMEKIND_MULTIPART;
@@ -1422,6 +1455,11 @@ CURLcode curl_mime_subparts(curl_mimepart *part,
return CURLE_OK;
}
+CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
+{
+ return Curl_mime_set_subparts(part, subparts, TRUE);
+}
+
/* Readback from top mime. */
/* Argument is the dummy top part. */
@@ -1485,7 +1523,7 @@ curl_off_t Curl_mime_size(curl_mimepart *part)
{
curl_off_t size;
- if(part->datasize < 0 && part->kind == MIMEKIND_MULTIPART)
+ if(part->kind == MIMEKIND_MULTIPART)
part->datasize = multipart_size(part->arg);
size = part->datasize;
@@ -1581,7 +1619,7 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
{
curl_mime *mime = NULL;
const char *boundary = NULL;
- char *s;
+ char *customct;
const char *cte = NULL;
CURLcode ret = CURLE_OK;
@@ -1593,12 +1631,14 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
if(part->state.state == MIMESTATE_CURLHEADERS)
mimesetstate(&part->state, MIMESTATE_CURLHEADERS, NULL);
- /* Build the content-type header. */
- s = search_header(part->userheaders, "Content-Type");
- if(s)
- contenttype = s;
- if(part->mimetype)
- contenttype = part->mimetype;
+ /* Check if content type is specified. */
+ customct = part->mimetype;
+ if(!customct)
+ customct = search_header(part->userheaders, "Content-Type");
+ if(customct)
+ contenttype = customct;
+
+ /* If content type is not specified, try to determine it. */
if(!contenttype) {
switch(part->kind) {
case MIMEKIND_MULTIPART:
@@ -1622,7 +1662,8 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
if(mime)
boundary = mime->boundary;
}
- else if(contenttype && strcasecompare(contenttype, "text/plain"))
+ else if(contenttype && !customct &&
+ strcasecompare(contenttype, "text/plain"))
if(strategy == MIMESTRATEGY_MAIL || !part->filename)
contenttype = NULL;
@@ -1816,6 +1857,15 @@ void Curl_mime_cleanpart(curl_mimepart *part)
(void) part;
}
+CURLcode Curl_mime_set_subparts(curl_mimepart *part,
+ curl_mime *subparts, int take_ownership)
+{
+ (void) part;
+ (void) subparts;
+ (void) take_ownership;
+ return CURLE_NOT_BUILT_IN;
+}
+
CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
const char *contenttype,
const char *disposition,
diff --git a/lib/mime.h b/lib/mime.h
index a14485707..7827f7412 100644
--- a/lib/mime.h
+++ b/lib/mime.h
@@ -122,6 +122,8 @@ struct curl_mimepart_s {
/* Prototypes. */
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy);
void Curl_mime_cleanpart(curl_mimepart *part);
+CURLcode Curl_mime_set_subparts(curl_mimepart *part,
+ curl_mime *subparts, int take_ownership);
CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
const char *contenttype,
const char *disposition,
diff --git a/lib/mk-ca-bundle.pl b/lib/mk-ca-bundle.pl
index cc36c7680..dcfec0bb6 100755
--- a/lib/mk-ca-bundle.pl
+++ b/lib/mk-ca-bundle.pl
@@ -47,11 +47,9 @@ eval "require LWP::UserAgent";
my %urls = (
'nss' =>
- 'https://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
+ 'https://hg.mozilla.org/projects/nss/raw-file/default/lib/ckfw/builtins/certdata.txt',
'central' =>
'https://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
- 'aurora' =>
- 'https://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
'beta' =>
'https://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
'release' =>
diff --git a/lib/multi.c b/lib/multi.c
index e2596801f..4b2628599 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -705,12 +705,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
curl_easy_cleanup is called. */
Curl_expire_clear(data);
- if(data->dns.hostcachetype == HCACHE_MULTI) {
- /* stop using the multi handle's DNS cache */
- data->dns.hostcache = NULL;
- data->dns.hostcachetype = HCACHE_NONE;
- }
-
if(data->easy_conn) {
/* we must call multi_done() here (if we still own the connection) so that
@@ -729,6 +723,13 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
Curl_getoff_all_pipelines(data, data->easy_conn);
}
+ if(data->dns.hostcachetype == HCACHE_MULTI) {
+ /* stop using the multi handle's DNS cache, *after* the possible
+ multi_done() call above */
+ data->dns.hostcache = NULL;
+ data->dns.hostcachetype = HCACHE_NONE;
+ }
+
Curl_wildcard_dtor(&data->wildcard);
/* destroy the timeout list that is held in the easy handle, do this *after*
@@ -2224,6 +2225,27 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
multi->type = 0; /* not good anymore */
+ /* Firsrt remove all remaining easy handles */
+ data = multi->easyp;
+ while(data) {
+ nextdata = data->next;
+ if(!data->state.done && data->easy_conn)
+ /* if DONE was never called for this handle */
+ (void)multi_done(&data->easy_conn, CURLE_OK, TRUE);
+ if(data->dns.hostcachetype == HCACHE_MULTI) {
+ /* clear out the usage of the shared DNS cache */
+ Curl_hostcache_clean(data, data->dns.hostcache);
+ data->dns.hostcache = NULL;
+ data->dns.hostcachetype = HCACHE_NONE;
+ }
+
+ /* Clear the pointer to the connection cache */
+ data->state.conn_cache = NULL;
+ data->multi = NULL; /* clear the association */
+
+ data = nextdata;
+ }
+
/* Close all the connections in the connection cache */
close_all_connections(multi);
@@ -2243,24 +2265,6 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
Curl_llist_destroy(&multi->msglist, NULL);
Curl_llist_destroy(&multi->pending, NULL);
- /* remove all easy handles */
- data = multi->easyp;
- while(data) {
- nextdata = data->next;
- if(data->dns.hostcachetype == HCACHE_MULTI) {
- /* clear out the usage of the shared DNS cache */
- Curl_hostcache_clean(data, data->dns.hostcache);
- data->dns.hostcache = NULL;
- data->dns.hostcachetype = HCACHE_NONE;
- }
-
- /* Clear the pointer to the connection cache */
- data->state.conn_cache = NULL;
- data->multi = NULL; /* clear the association */
-
- data = nextdata;
- }
-
Curl_hash_destroy(&multi->hostcache);
/* Free the blacklists by setting them to NULL */
diff --git a/lib/openldap.c b/lib/openldap.c
index 931719f97..274d70f02 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -677,7 +677,7 @@ ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
ber_slen_t ret;
CURLcode err = CURLE_RECV_ERROR;
- ret = li->recv(conn, FIRSTSOCKET, buf, len, &err);
+ ret = (li->recv)(conn, FIRSTSOCKET, buf, len, &err);
if(ret < 0 && err == CURLE_AGAIN) {
SET_SOCKERRNO(EWOULDBLOCK);
}
@@ -692,7 +692,7 @@ ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
ber_slen_t ret;
CURLcode err = CURLE_SEND_ERROR;
- ret = li->send(conn, FIRSTSOCKET, buf, len, &err);
+ ret = (li->send)(conn, FIRSTSOCKET, buf, len, &err);
if(ret < 0 && err == CURLE_AGAIN) {
SET_SOCKERRNO(EWOULDBLOCK);
}
diff --git a/lib/pingpong.c b/lib/pingpong.c
index b8f214005..ef865ae54 100644
--- a/lib/pingpong.c
+++ b/lib/pingpong.c
@@ -168,16 +168,22 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
char *s;
CURLcode result;
struct connectdata *conn = pp->conn;
- struct Curl_easy *data = conn->data;
+ struct Curl_easy *data;
#ifdef HAVE_GSSAPI
- enum protection_level data_sec = conn->data_prot;
+ enum protection_level data_sec;
#endif
DEBUGASSERT(pp->sendleft == 0);
DEBUGASSERT(pp->sendsize == 0);
DEBUGASSERT(pp->sendthis == NULL);
+ if(!conn)
+ /* can't send without a connection! */
+ return CURLE_SEND_ERROR;
+
+ data = conn->data;
+
fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */
if(!fmt_crlf)
return CURLE_OUT_OF_MEMORY;
@@ -205,6 +211,7 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
&bytes_written);
#ifdef HAVE_GSSAPI
+ data_sec = conn->data_prot;
DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
conn->data_prot = data_sec;
#endif
diff --git a/lib/sendf.c b/lib/sendf.c
index d2bc10b46..799f0ce13 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -241,25 +241,25 @@ void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
{
- va_list ap;
- size_t len;
- char error[CURL_ERROR_SIZE + 2];
- va_start(ap, fmt);
-
- vsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
- len = strlen(error);
+ if(data->set.verbose || data->set.errorbuffer) {
+ va_list ap;
+ size_t len;
+ char error[CURL_ERROR_SIZE + 2];
+ va_start(ap, fmt);
+ vsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
+ len = strlen(error);
- if(data->set.errorbuffer && !data->state.errorbuf) {
- strcpy(data->set.errorbuffer, error);
- data->state.errorbuf = TRUE; /* wrote error string */
- }
- if(data->set.verbose) {
- error[len] = '\n';
- error[++len] = '\0';
- Curl_debug(data, CURLINFO_TEXT, error, len, NULL);
+ if(data->set.errorbuffer && !data->state.errorbuf) {
+ strcpy(data->set.errorbuffer, error);
+ data->state.errorbuf = TRUE; /* wrote error string */
+ }
+ if(data->set.verbose) {
+ error[len] = '\n';
+ error[++len] = '\0';
+ Curl_debug(data, CURLINFO_TEXT, error, len, NULL);
+ }
+ va_end(ap);
}
-
- va_end(ap);
}
/* Curl_sendf() sends formatted data to the server */
diff --git a/lib/smtp.c b/lib/smtp.c
index 971236db7..bd3fc2e10 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -1188,6 +1188,9 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
if(!smtp || !pp->conn)
return CURLE_OK;
+ /* Cleanup our per-request based variables */
+ Curl_safefree(smtp->custom);
+
if(status) {
connclose(conn, "SMTP done with bad status"); /* marked for closure */
result = status; /* use the already set error code */
@@ -1246,9 +1249,6 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
result = smtp_block_statemach(conn);
}
- /* Cleanup our per-request based variables */
- Curl_safefree(smtp->custom);
-
/* Clear the transfer mode for the next request */
smtp->transfer = FTPTRANSFER_BODY;
diff --git a/lib/strtoofft.c b/lib/strtoofft.c
index 807fc5454..363647737 100644
--- a/lib/strtoofft.c
+++ b/lib/strtoofft.c
@@ -219,7 +219,10 @@ CURLofft curlx_strtoofft(const char *str, char **endp, int base,
curl_off_t number;
errno = 0;
*num = 0; /* clear by default */
- while(str && *str && ISSPACE(*str))
+
+ DEBUGASSERT(str);
+
+ while(*str && ISSPACE(*str))
str++;
if('-' == *str) {
if(endp)
diff --git a/lib/url.c b/lib/url.c
index 1e56b7d87..c538ca096 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -721,13 +721,14 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
char *argptr;
CURLcode result = CURLE_OK;
long arg;
-#ifndef CURL_DISABLE_HTTP
curl_off_t bigsize;
-#endif
switch(option) {
case CURLOPT_DNS_CACHE_TIMEOUT:
- data->set.dns_cache_timeout = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.dns_cache_timeout = arg;
break;
case CURLOPT_DNS_USE_GLOBAL_CACHE:
/* remember we want this enabled */
@@ -765,7 +766,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* Set the absolute number of maximum simultaneous alive connection that
* libcurl is allowed to have.
*/
- data->set.maxconnects = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.maxconnects = arg;
break;
case CURLOPT_FORBID_REUSE:
/*
@@ -875,7 +879,11 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* Option that specifies how quickly an server response must be obtained
* before it is considered failure. For pingpong protocols.
*/
- data->set.server_response_timeout = va_arg(param, long) * 1000;
+ arg = va_arg(param, long);
+ if((arg >= 0) && (arg < (INT_MAX/1000)))
+ data->set.server_response_timeout = arg * 1000;
+ else
+ return CURLE_BAD_FUNCTION_ARGUMENT;
break;
case CURLOPT_TFTP_NO_OPTIONS:
/*
@@ -888,7 +896,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* TFTP option that specifies the block size to use for data transmission.
*/
- data->set.tftp_blksize = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.tftp_blksize = arg;
break;
case CURLOPT_DIRLISTONLY:
/*
@@ -907,13 +918,19 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* How do access files over FTP.
*/
- data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < CURLFTPMETHOD_DEFAULT) || (arg > CURLFTPMETHOD_SINGLECWD))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.ftp_filemethod = (curl_ftpfile)arg;
break;
case CURLOPT_NETRC:
/*
* Parse the $HOME/.netrc file
*/
- data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < CURL_NETRC_IGNORED) || (arg > CURL_NETRC_REQUIRED))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.use_netrc = (enum CURL_NETRC_OPTION)arg;
break;
case CURLOPT_NETRC_FILE:
/*
@@ -936,7 +953,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* Set HTTP time condition. This must be one of the defines in the
* gnurl/curl.h header file.
*/
- data->set.timecondition = (curl_TimeCond)va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < CURL_TIMECOND_NONE) || (arg > CURL_TIMECOND_LASTMOD))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.timecondition = (curl_TimeCond)arg;
break;
case CURLOPT_TIMEVALUE:
/*
@@ -952,6 +972,8 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
*/
#ifdef USE_SSL
arg = va_arg(param, long);
+ if((arg < CURL_SSLVERSION_DEFAULT) || (arg > CURL_SSLVERSION_TLSv1_3))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.ssl.primary.version = C_SSLVERSION_VALUE(arg);
data->set.ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
#else
@@ -965,6 +987,8 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
*/
#ifdef USE_SSL
arg = va_arg(param, long);
+ if((arg < CURL_SSLVERSION_DEFAULT) || (arg > CURL_SSLVERSION_TLSv1_3))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.proxy_ssl.primary.version = C_SSLVERSION_VALUE(arg);
data->set.proxy_ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
#else
@@ -1022,7 +1046,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* The maximum amount of hops you allow curl to follow Location:
* headers. This should mostly be used to detect never-ending loops.
*/
- data->set.maxredirs = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.maxredirs = arg;
break;
case CURLOPT_POSTREDIR:
@@ -1037,6 +1064,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* other - POST is kept as POST after 301 and 302
*/
arg = va_arg(param, long);
+ if(arg < CURL_REDIR_GET_ALL)
+ /* no return error on too high numbers since the bitmask could be
+ extended in a future */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.keep_post = arg & CURL_REDIR_POST_ALL;
}
break;
@@ -1116,6 +1147,8 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* figure it out. Enables binary posts.
*/
bigsize = va_arg(param, long);
+ if(bigsize < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
if(data->set.postfieldsize < bigsize &&
data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
@@ -1158,10 +1191,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* Set to make us do MIME/form POST
*/
- result = curl_mime_subparts(&data->set.mimepost,
- va_arg(param, curl_mime *));
+ result = Curl_mime_set_subparts(&data->set.mimepost,
+ va_arg(param, curl_mime *), FALSE);
if(!result) {
- data->set.mimepost.freefunc = NULL; /* Avoid free upon easy cleanup. */
data->set.httpreq = HTTPREQ_POST_MIME;
data->set.opt_no_body = FALSE; /* this is implied */
}
@@ -1366,9 +1398,14 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* the listed enums in gnurl/curl.h.
*/
arg = va_arg(param, long);
+ if(arg < CURL_HTTP_VERSION_NONE)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
#ifndef USE_NGHTTP2
if(arg >= CURL_HTTP_VERSION_2)
return CURLE_UNSUPPORTED_PROTOCOL;
+#else
+ if(arg > CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE)
+ return CURLE_UNSUPPORTED_PROTOCOL;
#endif
data->set.httpversion = arg;
break;
@@ -1378,7 +1415,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* Time to wait for a response to a HTTP request containing an
* Expect: 100-continue header before sending the data anyway.
*/
- data->set.expect_100_timeout = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.expect_100_timeout = arg;
break;
#endif /* CURL_DISABLE_HTTP */
@@ -1460,7 +1500,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* Explicitly set HTTP proxy port number.
*/
- data->set.proxyport = va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < 0) || (arg > 65535))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.proxyport = arg;
break;
case CURLOPT_PROXYAUTH:
@@ -1543,7 +1586,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
*/
- data->set.proxytype = (curl_proxytype)va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.proxytype = (curl_proxytype)arg;
break;
case CURLOPT_PROXY_TRANSFER_MODE:
@@ -1642,7 +1688,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
break;
case CURLOPT_FTP_SSL_CCC:
- data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < CURLFTPSSL_CCC_NONE) || (arg > CURLFTPSSL_CCC_ACTIVE))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.ftp_ccc = (curl_ftpccc)arg;
break;
case CURLOPT_FTP_SKIP_PASV_IP:
@@ -1665,42 +1714,60 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* If known, this should inform curl about the file size of the
* to-be-uploaded file.
*/
- data->set.filesize = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.filesize = arg;
break;
case CURLOPT_INFILESIZE_LARGE:
/*
* If known, this should inform curl about the file size of the
* to-be-uploaded file.
*/
- data->set.filesize = va_arg(param, curl_off_t);
+ bigsize = va_arg(param, curl_off_t);
+ if(bigsize < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.filesize = bigsize;
break;
case CURLOPT_LOW_SPEED_LIMIT:
/*
* The low speed limit that if transfers are below this for
* CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
*/
- data->set.low_speed_limit = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.low_speed_limit = arg;
break;
case CURLOPT_MAX_SEND_SPEED_LARGE:
/*
* When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
* bytes per second the transfer is throttled..
*/
- data->set.max_send_speed = va_arg(param, curl_off_t);
+ bigsize = va_arg(param, curl_off_t);
+ if(bigsize < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.max_send_speed = bigsize;
break;
case CURLOPT_MAX_RECV_SPEED_LARGE:
/*
* When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
* second the transfer is throttled..
*/
- data->set.max_recv_speed = va_arg(param, curl_off_t);
+ bigsize = va_arg(param, curl_off_t);
+ if(bigsize < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.max_recv_speed = bigsize;
break;
case CURLOPT_LOW_SPEED_TIME:
/*
* The low speed time that if transfers are below the set
* CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
*/
- data->set.low_speed_time = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.low_speed_time = arg;
break;
case CURLOPT_URL:
/*
@@ -1719,36 +1786,56 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* The port number to use when getting the URL
*/
- data->set.use_port = va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < 0) || (arg > 65535))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.use_port = arg;
break;
case CURLOPT_TIMEOUT:
/*
* The maximum time you allow curl to use for a single transfer
* operation.
*/
- data->set.timeout = va_arg(param, long) * 1000L;
+ arg = va_arg(param, long);
+ if((arg >= 0) && (arg < (INT_MAX/1000)))
+ data->set.timeout = arg * 1000;
+ else
+ return CURLE_BAD_FUNCTION_ARGUMENT;
break;
case CURLOPT_TIMEOUT_MS:
- data->set.timeout = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.timeout = arg;
break;
case CURLOPT_CONNECTTIMEOUT:
/*
* The maximum time you allow curl to use to connect.
*/
- data->set.connecttimeout = va_arg(param, long) * 1000L;
+ arg = va_arg(param, long);
+ if((arg >= 0) && (arg < (INT_MAX/1000)))
+ data->set.connecttimeout = arg * 1000;
+ else
+ return CURLE_BAD_FUNCTION_ARGUMENT;
break;
case CURLOPT_CONNECTTIMEOUT_MS:
- data->set.connecttimeout = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.connecttimeout = arg;
break;
case CURLOPT_ACCEPTTIMEOUT_MS:
/*
* The maximum time you allow curl to wait for server connect
*/
- data->set.accepttimeout = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.accepttimeout = arg;
break;
case CURLOPT_USERPWD:
@@ -1897,13 +1984,19 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* Resume transfer at the given file position
*/
- data->set.set_resume_from = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < -1)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.set_resume_from = arg;
break;
case CURLOPT_RESUME_FROM_LARGE:
/*
* Resume transfer at the given file position
*/
- data->set.set_resume_from = va_arg(param, curl_off_t);
+ bigsize = va_arg(param, curl_off_t);
+ if(bigsize < -1)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.set_resume_from = bigsize;
break;
case CURLOPT_DEBUGFUNCTION:
/*
@@ -2132,9 +2225,12 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
break;
case CURLOPT_GSSAPI_DELEGATION:
/*
- * GSS-API credential delegation
+ * GSS-API credential delegation bitmask
*/
- data->set.gssapi_delegation = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < CURLGSSAPI_DELEGATION_NONE)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.gssapi_delegation = arg;
break;
case CURLOPT_SSL_VERIFYPEER:
/*
@@ -2142,6 +2238,12 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
*/
data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ?
TRUE : FALSE;
+
+ /* Update the current connection ssl_config. */
+ if(data->easy_conn) {
+ data->easy_conn->ssl_config.verifypeer =
+ data->set.ssl.primary.verifypeer;
+ }
break;
case CURLOPT_PROXY_SSL_VERIFYPEER:
/*
@@ -2149,6 +2251,12 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
*/
data->set.proxy_ssl.primary.verifypeer =
(0 != va_arg(param, long))?TRUE:FALSE;
+
+ /* Update the current connection proxy_ssl_config. */
+ if(data->easy_conn) {
+ data->easy_conn->proxy_ssl_config.verifypeer =
+ data->set.proxy_ssl.primary.verifypeer;
+ }
break;
case CURLOPT_SSL_VERIFYHOST:
/*
@@ -2167,6 +2275,12 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
}
data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE;
+
+ /* Update the current connection ssl_config. */
+ if(data->easy_conn) {
+ data->easy_conn->ssl_config.verifyhost =
+ data->set.ssl.primary.verifyhost;
+ }
break;
case CURLOPT_PROXY_SSL_VERIFYHOST:
/*
@@ -2185,6 +2299,12 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
}
data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE;
+
+ /* Update the current connection proxy_ssl_config. */
+ if(data->easy_conn) {
+ data->easy_conn->proxy_ssl_config.verifyhost =
+ data->set.proxy_ssl.primary.verifyhost;
+ }
break;
case CURLOPT_SSL_VERIFYSTATUS:
/*
@@ -2197,6 +2317,12 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ?
TRUE : FALSE;
+
+ /* Update the current connection ssl_config. */
+ if(data->easy_conn) {
+ data->easy_conn->ssl_config.verifystatus =
+ data->set.ssl.primary.verifystatus;
+ }
break;
case CURLOPT_SSL_CTX_FUNCTION:
/*
@@ -2447,7 +2573,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* Set the maximum size of a file to download.
*/
- data->set.max_filesize = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.max_filesize = arg;
break;
#ifdef USE_SSL
@@ -2455,7 +2584,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* Make transfers attempt to use SSL/TLS.
*/
- data->set.use_ssl = (curl_usessl)va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < CURLUSESSL_NONE) || (arg > CURLUSESSL_ALL))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.use_ssl = (curl_usessl)arg;
break;
case CURLOPT_SSL_OPTIONS:
@@ -2475,18 +2607,27 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* Set a specific auth for FTP-SSL transfers.
*/
- data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < CURLFTPAUTH_DEFAULT) || (arg > CURLFTPAUTH_TLS))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.ftpsslauth = (curl_ftpauth)arg;
break;
case CURLOPT_IPRESOLVE:
- data->set.ipver = va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.ipver = arg;
break;
case CURLOPT_MAXFILESIZE_LARGE:
/*
* Set the maximum size of a file to download.
*/
- data->set.max_filesize = va_arg(param, curl_off_t);
+ bigsize = va_arg(param, curl_off_t);
+ if(bigsize < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.max_filesize = bigsize;
break;
case CURLOPT_TCP_NODELAY:
@@ -2571,6 +2712,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
#ifdef USE_LIBSSH2
/* we only include SSH options if explicitly built to support SSH */
case CURLOPT_SSH_AUTH_TYPES:
+ arg = va_arg(param, long);
+ if(arg < CURLSSH_AUTH_NONE)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.ssh_auth_types = va_arg(param, long);
break;
@@ -2640,14 +2784,20 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
/*
* Uses these permissions instead of 0644
*/
- data->set.new_file_perms = va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < 0) || (arg > 0777))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.new_file_perms = arg;
break;
case CURLOPT_NEW_DIRECTORY_PERMS:
/*
* Uses these permissions instead of 0755
*/
- data->set.new_directory_perms = va_arg(param, long);
+ arg = va_arg(param, long);
+ if((arg < 0) || (arg > 0777))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.new_directory_perms = arg;
break;
case CURLOPT_ADDRESS_SCOPE:
@@ -2894,10 +3044,16 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE;
break;
case CURLOPT_TCP_KEEPIDLE:
- data->set.tcp_keepidle = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.tcp_keepidle = arg;
break;
case CURLOPT_TCP_KEEPINTVL:
- data->set.tcp_keepintvl = va_arg(param, long);
+ arg = va_arg(param, long);
+ if(arg < 0)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.tcp_keepintvl = arg;
break;
case CURLOPT_TCP_FASTOPEN:
#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN)
diff --git a/lib/urldata.h b/lib/urldata.h
index 6dc715394..fc9549608 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1454,7 +1454,7 @@ enum dupstring {
STRING_PROXY_SERVICE_NAME, /* Proxy service name */
#endif
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
- defined(USE_SPNEGO)
+ defined(USE_SPNEGO) || defined(HAVE_GSSAPI)
STRING_SERVICE_NAME, /* Service name */
#endif
STRING_MAIL_FROM,
diff --git a/lib/vtls/axtls.c b/lib/vtls/axtls.c
index 6b42708d8..9294f49ed 100644
--- a/lib/vtls/axtls.c
+++ b/lib/vtls/axtls.c
@@ -728,7 +728,7 @@ const struct Curl_ssl Curl_ssl_axtls = {
Curl_axtls_connect, /* connect */
Curl_axtls_connect_nonblocking, /* connect_nonblocking */
Curl_axtls_get_internals, /* get_internals */
- Curl_axtls_close, /* close */
+ Curl_axtls_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_axtls_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c
index ba5ee1548..e06522304 100644
--- a/lib/vtls/cyassl.c
+++ b/lib/vtls/cyassl.c
@@ -1003,7 +1003,7 @@ const struct Curl_ssl Curl_ssl_cyassl = {
Curl_cyassl_connect, /* connect */
Curl_cyassl_connect_nonblocking, /* connect_nonblocking */
Curl_cyassl_get_internals, /* get_internals */
- Curl_cyassl_close, /* close */
+ Curl_cyassl_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_cyassl_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index a98f43307..316904224 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
+ * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
* Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
@@ -22,7 +22,7 @@
***************************************************************************/
/*
- * Source file for all iOS and Mac OS X SecureTransport-specific code for the
+ * Source file for all iOS and macOS SecureTransport-specific code for the
* TLS/SSL layer. No code but vtls.c should ever call or use these functions.
*/
@@ -50,12 +50,14 @@
#include <CoreFoundation/CoreFoundation.h>
#include <CommonCrypto/CommonDigest.h>
-/* The Security framework has changed greatly between iOS and different OS X
+/* The Security framework has changed greatly between iOS and different macOS
versions, and we will try to support as many of them as we can (back to
Leopard and iOS 5) by using macros and weak-linking.
- IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
- you must build this project against the 10.8 SDK or later. */
+ In general, you want to build this using the most recent OS SDK, since some
+ features require curl to be built against the latest SDK. TLS 1.1 and 1.2
+ support, for instance, require the macOS 10.8 SDK or later. TLS 1.3
+ requires the macOS 10.13 or iOS 11 SDK or later. */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
@@ -64,6 +66,7 @@
#define CURL_BUILD_IOS 0
#define CURL_BUILD_IOS_7 0
+#define CURL_BUILD_IOS_11 0
#define CURL_BUILD_MAC 1
/* This is the maximum API level we are allowed to use when building: */
#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
@@ -71,10 +74,11 @@
#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
+#define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
/* These macros mean "the following code is present to allow runtime backward
compatibility with at least this cat or earlier":
- (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
- environmental variable.) */
+ (You set this at build-time using the compiler command line option
+ "-mmacos-version-min.") */
#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
@@ -84,11 +88,14 @@
#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
#define CURL_BUILD_IOS 1
#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
+#define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
#define CURL_BUILD_MAC 0
#define CURL_BUILD_MAC_10_5 0
#define CURL_BUILD_MAC_10_6 0
#define CURL_BUILD_MAC_10_7 0
#define CURL_BUILD_MAC_10_8 0
+#define CURL_BUILD_MAC_10_9 0
+#define CURL_BUILD_MAC_10_13 0
#define CURL_SUPPORT_MAC_10_5 0
#define CURL_SUPPORT_MAC_10_6 0
#define CURL_SUPPORT_MAC_10_7 0
@@ -838,6 +845,30 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
return "TLS_RSA_PSK_WITH_NULL_SHA384";
break;
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */
+ case TLS_AES_128_GCM_SHA256:
+ return "TLS_AES_128_GCM_SHA256";
+ break;
+ case TLS_AES_256_GCM_SHA384:
+ return "TLS_AES_256_GCM_SHA384";
+ break;
+ case TLS_CHACHA20_POLY1305_SHA256:
+ return "TLS_CHACHA20_POLY1305_SHA256";
+ break;
+ case TLS_AES_128_CCM_SHA256:
+ return "TLS_AES_128_CCM_SHA256";
+ break;
+ case TLS_AES_128_CCM_8_SHA256:
+ return "TLS_AES_128_CCM_8_SHA256";
+ break;
+ case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+ return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
+ break;
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
}
return "TLS_NULL_WITH_NULL_NULL";
}
@@ -1171,6 +1202,15 @@ static CURLcode darwinssl_version_from_curl(SSLProtocol *darwinver,
*darwinver = kTLSProtocol12;
return CURLE_OK;
case CURL_SSLVERSION_TLSv1_3:
+ /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ /* We can assume __builtin_available() will always work in the
+ 10.13/11.0 SDK: */
+ if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
+ *darwinver = kTLSProtocol13;
+ return CURLE_OK;
+ }
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
break;
}
return CURLE_SSL_CONNECT_ERROR;
@@ -1184,12 +1224,27 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
long ssl_version = SSL_CONN_CONFIG(version);
long ssl_version_max = SSL_CONN_CONFIG(version_max);
+ long max_supported_version_by_os;
+
+ /* macOS 10.5-10.7 supported TLS 1.0 only.
+ macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
+ macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
+ max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3;
+ }
+ else {
+ max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
+ }
+#else
+ max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
switch(ssl_version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
ssl_version = CURL_SSLVERSION_TLSv1_0;
- ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+ ssl_version_max = max_supported_version_by_os;
break;
}
@@ -1198,7 +1253,7 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
ssl_version_max = ssl_version << 16;
break;
case CURL_SSLVERSION_MAX_DEFAULT:
- ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+ ssl_version_max = max_supported_version_by_os;
break;
}
@@ -1247,7 +1302,7 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
true);
break;
case CURL_SSLVERSION_TLSv1_3:
- failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
+ failf(data, "Your version of the OS does not support TLSv1.3");
return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -1326,7 +1381,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
(void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
+ (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol13);
+ }
+ else {
+ (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+ }
+#else
(void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
break;
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
@@ -2341,7 +2405,13 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
infof(data, "TLS 1.2 connection using %s\n",
TLSCipherNameForNumber(cipher));
break;
-#endif
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ case kTLSProtocol13:
+ infof(data, "TLS 1.3 connection using %s\n",
+ TLSCipherNameForNumber(cipher));
+ break;
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
default:
infof(data, "Unknown protocol connection\n");
break;
@@ -2932,7 +3002,7 @@ const struct Curl_ssl Curl_ssl_darwinssl = {
Curl_darwinssl_connect, /* connect */
Curl_darwinssl_connect_nonblocking, /* connect_nonblocking */
Curl_darwinssl_get_internals, /* get_internals */
- Curl_darwinssl_close, /* close */
+ Curl_darwinssl_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_darwinssl_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index ec142fb9e..6050fd1a7 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -1375,7 +1375,7 @@ const struct Curl_ssl Curl_ssl_gskit = {
Curl_gskit_connect, /* connect */
Curl_gskit_connect_nonblocking, /* connect_nonblocking */
Curl_gskit_get_internals, /* get_internals */
- Curl_gskit_close, /* close */
+ Curl_gskit_close, /* close_one */
Curl_none_close_all, /* close_all */
/* No session handling for GSKit */
Curl_none_session_free, /* session_free */
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index a844915ef..30b255b81 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -1827,7 +1827,7 @@ const struct Curl_ssl Curl_ssl_gnutls = {
Curl_gtls_connect, /* connect */
Curl_gtls_connect_nonblocking, /* connect_nonblocking */
Curl_gtls_get_internals, /* get_internals */
- Curl_gtls_close, /* close */
+ Curl_gtls_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_gtls_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index ce1f8eba8..28251a388 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -1061,7 +1061,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
Curl_mbedtls_connect, /* connect */
Curl_mbedtls_connect_nonblocking, /* connect_nonblocking */
Curl_mbedtls_get_internals, /* get_internals */
- Curl_mbedtls_close, /* close */
+ Curl_mbedtls_close, /* close_one */
Curl_mbedtls_close_all, /* close_all */
Curl_mbedtls_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index c0b7e63ab..a3ef37a12 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -2365,7 +2365,7 @@ const struct Curl_ssl Curl_ssl_nss = {
Curl_nss_connect, /* connect */
Curl_nss_connect_nonblocking, /* connect_nonblocking */
Curl_nss_get_internals, /* get_internals */
- Curl_nss_close, /* close */
+ Curl_nss_close, /* close_one */
Curl_none_close_all, /* close_all */
/* NSS has its own session ID cache */
Curl_none_session_free, /* session_free */
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 4253160aa..f94415222 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -69,7 +69,9 @@
#include <openssl/bio.h>
#include <openssl/buffer.h>
-#ifdef HAVE_OPENSSL_PKCS12_H
+#ifndef OPENSSL_IS_BORINGSSL
+/* BoringSSL does not support PKCS12 */
+#define HAVE_PKCS12_SUPPORT 1
#include <openssl/pkcs12.h>
#endif
@@ -151,14 +153,13 @@ static unsigned long OpenSSL_version_num(void)
/*
* Whether SSL_CTX_set_keylog_callback is available.
* OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287
- * BoringSSL: supported since d28f59c27bac (committed 2015-11-19), the
- * BORINGSSL_201512 macro from 2016-01-21 should be close enough.
+ * BoringSSL: supported since d28f59c27bac (committed 2015-11-19)
* LibreSSL: unsupported in at least 2.5.1 (explicitly check for it since it
* lies and pretends to be OpenSSL 2.0.0).
*/
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || \
- defined(BORINGSSL_201512)
+ defined(OPENSSL_IS_BORINGSSL)
#define HAVE_KEYLOG_CALLBACK
#endif
@@ -653,7 +654,7 @@ int cert_stuff(struct connectdata *conn,
case SSL_FILETYPE_PKCS12:
{
-#ifdef HAVE_OPENSSL_PKCS12_H
+#ifdef HAVE_PKCS12_SUPPORT
FILE *f;
PKCS12 *p12;
EVP_PKEY *pri;
@@ -837,7 +838,7 @@ int cert_stuff(struct connectdata *conn,
EVP_PKEY_free(pktmp);
}
-#ifndef OPENSSL_NO_RSA
+#if !defined(OPENSSL_NO_RSA) && defined(HAVE_OPAQUE_EVP_PKEY)
{
/* If RSA is used, don't check the private key if its flags indicate
* it doesn't support it. */
@@ -3636,7 +3637,7 @@ const struct Curl_ssl Curl_ssl_openssl = {
Curl_ossl_connect, /* connect */
Curl_ossl_connect_nonblocking, /* connect_nonblocking */
Curl_ossl_get_internals, /* get_internals */
- Curl_ossl_close, /* close */
+ Curl_ossl_close, /* close_one */
Curl_ossl_close_all, /* close_all */
Curl_ossl_session_free, /* session_free */
Curl_ossl_set_engine, /* set_engine */
diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c
index fc0644f89..df29fa945 100644
--- a/lib/vtls/polarssl.c
+++ b/lib/vtls/polarssl.c
@@ -923,7 +923,7 @@ const struct Curl_ssl Curl_ssl_polarssl = {
Curl_polarssl_connect, /* connect */
Curl_polarssl_connect_nonblocking, /* connect_nonblocking */
Curl_polarssl_get_internals, /* get_internals */
- Curl_polarssl_close, /* close */
+ Curl_polarssl_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_polarssl_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 9ca1431bd..85c64cf44 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -1838,7 +1838,7 @@ const struct Curl_ssl Curl_ssl_schannel = {
Curl_schannel_connect, /* connect */
Curl_schannel_connect_nonblocking, /* connect_nonblocking */
Curl_schannel_get_internals, /* get_internals */
- Curl_schannel_close, /* close */
+ Curl_schannel_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_schannel_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index bb8fda419..56e631771 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -549,7 +549,7 @@ int Curl_ssl_getsock(struct connectdata *conn,
void Curl_ssl_close(struct connectdata *conn, int sockindex)
{
DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
- Curl_ssl->close(conn, sockindex);
+ Curl_ssl->close_one(conn, sockindex);
}
CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
@@ -1059,6 +1059,7 @@ bool Curl_none_false_start(void)
return FALSE;
}
+#ifndef CURL_DISABLE_CRYPTO_AUTH
CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
unsigned char *md5sum, size_t md5len UNUSED_PARAM)
{
@@ -1073,6 +1074,19 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
Curl_MD5_final(MD5pw, md5sum);
return CURLE_OK;
}
+#else
+CURLcode Curl_none_md5sum(unsigned char *input UNUSED_PARAM,
+ size_t inputlen UNUSED_PARAM,
+ unsigned char *md5sum UNUSED_PARAM,
+ size_t md5len UNUSED_PARAM)
+{
+ (void)input;
+ (void)inputlen;
+ (void)md5sum;
+ (void)md5len;
+ return CURLE_NOT_BUILT_IN;
+}
+#endif
static int Curl_multissl_init(void)
{
@@ -1108,7 +1122,7 @@ static void Curl_multissl_close(struct connectdata *conn, int sockindex)
{
if(multissl_init(NULL))
return;
- Curl_ssl->close(conn, sockindex);
+ Curl_ssl->close_one(conn, sockindex);
}
static const struct Curl_ssl Curl_ssl_multi = {
@@ -1133,7 +1147,7 @@ static const struct Curl_ssl Curl_ssl_multi = {
Curl_multissl_connect, /* connect */
Curl_multissl_connect_nonblocking, /* connect_nonblocking */
Curl_multissl_get_internals, /* get_internals */
- Curl_multissl_close, /* close */
+ Curl_multissl_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_none_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index f1a11ea58..c5f9d4a3f 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -60,7 +60,7 @@ struct Curl_ssl {
CURLcode (*connect_nonblocking)(struct connectdata *conn, int sockindex,
bool *done);
void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info);
- void (*close)(struct connectdata *conn, int sockindex);
+ void (*close_one)(struct connectdata *conn, int sockindex);
void (*close_all)(struct Curl_easy *data);
void (*session_free)(void *ptr);
diff --git a/packages/OS400/README.OS400 b/packages/OS400/README.OS400
index aee131bf5..831172c28 100644
--- a/packages/OS400/README.OS400
+++ b/packages/OS400/README.OS400
@@ -241,7 +241,8 @@ _ If data compression has to be supported, ZLIB development environment must
be installed.
_ Likewise, if SCP and SFTP protocols have to be compiled in, LIBSSH2
developent environment must be installed.
-_ Install the curl source directory in IFS.
+_ Install the curl source directory in IFS. Do NOT install it in the
+ installation target directory (wich defaults to /curl).
_ Enter shell (QSH)
_ Change current directory to the curl installation directory
_ Change current directory to ./packages/OS400
diff --git a/packages/OS400/makefile.sh b/packages/OS400/makefile.sh
index 141d8778c..7c6bcd7c6 100644
--- a/packages/OS400/makefile.sh
+++ b/packages/OS400/makefile.sh
@@ -31,10 +31,11 @@ fi
for TEXT in "${TOPDIR}/COPYING" "${SCRIPTDIR}/README.OS400" \
"${TOPDIR}/CHANGES" "${TOPDIR}/docs/THANKS" "${TOPDIR}/docs/FAQ" \
- "${TOPDIR}/docs/FEATURES" "${TOPDIR}/docs/SSLCERTS" \
+ "${TOPDIR}/docs/FEATURES" "${TOPDIR}/docs/SSLCERTS.md" \
"${TOPDIR}/docs/RESOURCES" "${TOPDIR}/docs/VERSIONS" \
- "${TOPDIR}/docs/HISTORY"
+ "${TOPDIR}/docs/HISTORY.md"
do MEMBER="`basename \"${TEXT}\" .OS400`"
+ MEMBER="`basename \"${MEMBER}\" .md`"
MEMBER="${LIBIFSNAME}/DOCS.FILE/`db2_name \"${MEMBER}\"`.MBR"
if action_needed "${MEMBER}" "${TEXT}"
diff --git a/src/Makefile.m32 b/src/Makefile.m32
index 836fa2738..21e3a6bc0 100644
--- a/src/Makefile.m32
+++ b/src/Makefile.m32
@@ -22,7 +22,7 @@
###########################################################################
#
-## Makefile for building curl.exe with MingW (GCC-3.2 or later)
+## Makefile for building curl.exe with MingW (GCC-3.2 or later or LLVM/Clang)
## and optionally OpenSSL (1.0.2a), libssh2 (1.5), zlib (1.2.8), librtmp (2.4)
##
## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
@@ -88,12 +88,19 @@ ifndef LIBCARES_PATH
LIBCARES_PATH = $(PROOT)/ares
endif
-CC = $(CROSSPREFIX)gcc
+ifeq ($(CURL_CC),)
+CURL_CC := $(CROSSPREFIX)gcc
+endif
+ifeq ($(CURL_AR),)
+CURL_AR := $(CROSSPREFIX)ar
+endif
+
+CC = $(CURL_CC)
CFLAGS = $(CURL_CFLAG_EXTRAS) -g -O2 -Wall -W
CFLAGS += -fno-strict-aliasing
# comment LDFLAGS below to keep debug info
LDFLAGS = $(CURL_LDFLAG_EXTRAS) $(CURL_LDFLAG_EXTRAS_EXE) -s
-AR = $(CROSSPREFIX)ar
+AR = $(CURL_AR)
RC = $(CROSSPREFIX)windres
RCFLAGS = --include-dir=$(PROOT)/include -O COFF
STRIP = $(CROSSPREFIX)strip -g
diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c
index bb982d2e4..7f2181f40 100644
--- a/src/tool_cb_hdr.c
+++ b/src/tool_cb_hdr.c
@@ -161,8 +161,13 @@ static char *parse_filename(const char *ptr, size_t len)
else
stop = ';';
+ /* scan for the end letter and stop there */
+ q = strchr(p, stop);
+ if(q)
+ *q = '\0';
+
/* if the filename contains a path, only use filename portion */
- q = strrchr(copy, '/');
+ q = strrchr(p, '/');
if(q) {
p = q + 1;
if(!*p) {
@@ -183,14 +188,6 @@ static char *parse_filename(const char *ptr, size_t len)
}
}
- /* scan for the end letter and stop there */
- for(q = p; *q; ++q) {
- if(*q == stop) {
- *q = '\0';
- break;
- }
- }
-
/* make sure the file name doesn't end in \r or \n */
q = strchr(p, '\r');
if(q)
diff --git a/src/tool_formparse.c b/src/tool_formparse.c
index 4645a761e..b763d88a5 100644
--- a/src/tool_formparse.c
+++ b/src/tool_formparse.c
@@ -31,10 +31,21 @@
#include "tool_cfgable.h"
#include "tool_convert.h"
#include "tool_msgs.h"
+#include "tool_binmode.h"
+#include "tool_getparam.h"
+#include "tool_paramhlp.h"
#include "tool_formparse.h"
#include "memdebug.h" /* keep this as LAST include */
+/* Stdin parameters. */
+typedef struct {
+ char *data; /* Memory data. */
+ curl_off_t origin; /* File read origin offset. */
+ curl_off_t size; /* Data size. */
+ curl_off_t curpos; /* Current read position. */
+} standard_input;
+
/*
* helper function to get a word from form param
@@ -372,16 +383,123 @@ static int get_param_part(struct OperationConfig *config, char **str,
return sep & 0xFF;
}
-/* Check if file is "-". If so, use a callback to read OUR stdin (to
+
+/* Mime part callbacks for stdin. */
+static size_t stdin_read(char *buffer, size_t size, size_t nitems, void *arg)
+{
+ standard_input *sip = (standard_input *) arg;
+ curl_off_t bytesleft;
+ (void) size; /* Always 1: ignored. */
+
+ if(sip->curpos >= sip->size)
+ return 0; /* At eof. */
+ bytesleft = sip->size - sip->curpos;
+ if((curl_off_t) nitems > bytesleft)
+ nitems = (size_t) bytesleft;
+ if(sip->data) {
+ /* Return data from memory. */
+ memcpy(buffer, sip->data + (size_t) sip->curpos, nitems);
+ }
+ else {
+ /* Read from stdin. */
+ nitems = fread(buffer, 1, nitems, stdin);
+ }
+ sip->curpos += nitems;
+ return nitems;
+}
+
+static int stdin_seek(void *instream, curl_off_t offset, int whence)
+{
+ standard_input *sip = (standard_input *) instream;
+
+ switch(whence) {
+ case SEEK_CUR:
+ offset += sip->curpos;
+ break;
+ case SEEK_END:
+ offset += sip->size;
+ break;
+ }
+ if(offset < 0)
+ return CURL_SEEKFUNC_CANTSEEK;
+ if(!sip->data) {
+ if(fseek(stdin, (long) (offset + sip->origin), SEEK_SET))
+ return CURL_SEEKFUNC_CANTSEEK;
+ }
+ sip->curpos = offset;
+ return CURL_SEEKFUNC_OK;
+}
+
+static void stdin_free(void *ptr)
+{
+ standard_input *sip = (standard_input *) ptr;
+
+ Curl_safefree(sip->data);
+ free(sip);
+}
+
+/* Set a part's data from a file, taking care about the pseudo filename "-" as
+ * a shortcut to read stdin: if so, use a callback to read OUR stdin (to
* workaround Windows DLL file handle caveat).
- * Else use curl_mime_filedata(). */
+ * If stdin is a regular file opened in binary mode, save current offset as
+ * origin for rewind and do not buffer data. Else read to EOF and keep in
+ * memory. In all cases, compute the stdin data size.
+ */
static CURLcode file_or_stdin(curl_mimepart *part, const char *file)
{
+ standard_input *sip = NULL;
+ int fd = -1;
+ CURLcode result = CURLE_OK;
+ struct_stat sbuf;
+
if(strcmp(file, "-"))
return curl_mime_filedata(part, file);
- return curl_mime_data_cb(part, -1, (curl_read_callback) fread,
- (curl_seek_callback) fseek, NULL, stdin);
+ sip = (standard_input *) malloc(sizeof *sip);
+ if(!sip)
+ return CURLE_OUT_OF_MEMORY;
+
+ memset((char *) sip, 0, sizeof *sip);
+ set_binmode(stdin);
+
+ /* If stdin is a regular file, do not buffer data but read it when needed. */
+ fd = fileno(stdin);
+ sip->origin = ftell(stdin);
+ if(fd >= 0 && sip->origin >= 0 && !fstat(fd, &sbuf) &&
+#ifdef __VMS
+ sbuf.st_fab_rfm != FAB$C_VAR && sbuf.st_fab_rfm != FAB$C_VFC &&
+#endif
+ S_ISREG(sbuf.st_mode)) {
+ sip->size = sbuf.st_size - sip->origin;
+ if(sip->size < 0)
+ sip->size = 0;
+ }
+ else { /* Not suitable for direct use, buffer stdin data. */
+ size_t stdinsize = 0;
+
+ sip->origin = 0;
+ if(file2memory(&sip->data, &stdinsize, stdin) != PARAM_OK)
+ result = CURLE_OUT_OF_MEMORY;
+ else {
+ if(!stdinsize)
+ sip->data = NULL; /* Has been freed if no data. */
+ sip->size = stdinsize;
+ if(ferror(stdin))
+ result = CURLE_READ_ERROR;
+ }
+ }
+
+ /* Set remote file name. */
+ if(!result)
+ result = curl_mime_filename(part, file);
+
+ /* Set part's data from callback. */
+ if(!result)
+ result = curl_mime_data_cb(part, sip->size,
+ stdin_read, stdin_seek, stdin_free, sip);
+ if(result)
+ stdin_free(sip);
+ return result;
}
@@ -650,7 +768,7 @@ int formparse(struct OperationConfig *config,
if(*contp == '<' && !literal_value) {
++contp;
sep = get_param_part(config, &contp,
- &data, &type, &filename, &encoder, &headers);
+ &data, &type, NULL, &encoder, &headers);
if(sep < 0) {
Curl_safefree(contents);
return 21;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3d1848992..d6e6cfe29 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -53,7 +53,7 @@ DIST_UNIT = unit
endif
SUBDIRS = certs data server libtest $(BUILD_UNIT)
-DIST_SUBDIRS = $(SUBDIRS) $(DIST_UNIT) fuzz
+DIST_SUBDIRS = $(SUBDIRS) $(DIST_UNIT)
PERLFLAGS = -I$(srcdir)
diff --git a/tests/data/DISABLED b/tests/data/DISABLED
index 11d54b463..fcbf0ffc4 100644
--- a/tests/data/DISABLED
+++ b/tests/data/DISABLED
@@ -18,3 +18,5 @@
1510
# Pipelining test that is causing false positives a little too often
1903
+# causes memory leaks for now:
+1553
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 4243c2183..eaa1bbced 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -47,7 +47,7 @@ test208 test209 test210 test211 test212 test213 test214 test215 test216 \
test217 test218 test219 test220 test221 test222 test223 test224 test225 \
test226 test227 test228 test229 test231 test233 test234 \
test235 test236 test237 test238 test239 test240 test241 test242 test243 \
- test245 test246 test247 test248 test249 test250 test251 test252 \
+test244 test245 test246 test247 test248 test249 test250 test251 test252 \
test253 test254 test255 test256 test257 test258 test259 test260 test261 \
test262 test263 test264 test265 test266 test267 test268 test269 test270 \
test271 test272 test273 test274 test275 test276 test277 test278 test279 \
@@ -70,7 +70,7 @@ test536 test537 test538 test539 test540 test541 test542 test543 test544 \
test545 test546 test547 test548 test549 test550 test551 test552 test553 \
test554 test555 test556 test557 test558 test559 test560 test561 test562 \
test563 test564 test565 test566 test567 test568 test569 test570 test571 \
-test572 test573 test574 test575 test576 test578 test579 test580 \
+test572 test573 test574 test575 test576 test577 test578 test579 test580 \
test581 test582 test583 test584 test585 test586 test587 test588 test589 \
test590 test591 test592 test593 test594 test595 test596 test597 test598 \
test599 test600 test601 test602 test603 test604 test605 test606 test607 \
@@ -78,7 +78,8 @@ test608 test609 test610 test611 test612 test613 test614 test615 test616 \
test617 test618 test619 test620 test621 test622 test623 test624 test625 \
test626 test627 test628 test629 test630 test631 test632 test633 test634 \
test635 test636 test637 test638 test639 test640 test641 test642 \
-test643 test644 test645 test646 test647 test648 test649 test650 \
+test643 test644 test645 test646 test647 test648 test649 test650 test651 \
+test652 test653 \
\
test700 test701 test702 test703 test704 test705 test706 test707 test708 \
test709 test710 test711 test712 test713 test714 test715 \
@@ -101,7 +102,7 @@ test909 test910 test911 test912 test913 test914 test915 test916 test917 \
test918 test919 test920 test921 test922 test923 test924 test925 test926 \
test927 test928 test929 test930 test931 test932 test933 test934 test935 \
test936 test937 test938 test939 test940 test941 test942 test943 test944 \
-test945 test946 test947 test948 test949 \
+test945 test946 test947 test948 test949 test950 \
\
test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
@@ -169,7 +170,7 @@ test1520 test1521 \
test1525 test1526 test1527 test1528 test1529 test1530 test1531 test1532 \
test1533 test1534 test1535 test1536 test1537 test1538 \
test1540 \
-test1550 test1551 \
+test1550 test1551 test1552 test1553 \
test1600 test1601 test1602 test1603 test1604 test1605 test1606 \
\
test1700 test1701 test1702 \
diff --git a/tests/data/test1422 b/tests/data/test1422
index 9b436cc4e..df9d750dd 100644
--- a/tests/data/test1422
+++ b/tests/data/test1422
@@ -16,7 +16,7 @@ Server: test-server/fake
Content-Length: 0
Connection: close
Content-Type: text/html
-Content-Disposition: filename=name1422; charset=funny; option=strange
+Content-Disposition: filename=name1422; charset=funny; option=str//nge
</data>
</reply>
diff --git a/tests/data/test1552 b/tests/data/test1552
new file mode 100644
index 000000000..c5b1b5728
--- /dev/null
+++ b/tests/data/test1552
@@ -0,0 +1,52 @@
+<testcase>
+<info>
+<keywords>
+IMAP
+Clear Text
+FETCH
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+From: me@somewhere
+To: fake@nowhere
+
+body
+
+--
+ yours sincerely
+</data>
+<datacheck>
+</datacheck>
+<servercmd>
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+imap
+</server>
+ <name>
+IMAP multi transfer error without curl_multi_remove_handle
+ </name>
+# tool is what to use instead of 'curl'
+<tool>
+lib1552
+</tool>
+ <command>
+'imap://%HOSTIP:%IMAPPORT/1552/;UID=1'
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test1553 b/tests/data/test1553
new file mode 100644
index 000000000..c2fb9cc32
--- /dev/null
+++ b/tests/data/test1553
@@ -0,0 +1,52 @@
+<testcase>
+<info>
+<keywords>
+IMAP
+Clear Text
+FETCH
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+From: me@somewhere
+To: fake@nowhere
+
+body
+
+--
+ yours sincerely
+</data>
+<datacheck>
+</datacheck>
+<servercmd>
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+imap
+</server>
+ <name>
+IMAP cleanup before a connection was created
+ </name>
+# tool is what to use instead of 'curl'
+<tool>
+lib1553
+</tool>
+ <command>
+imap://non-existing-host.haxx.se:%IMAPPORT/1553
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test173 b/tests/data/test173
index 754950105..865ef7ba2 100644
--- a/tests/data/test173
+++ b/tests/data/test173
@@ -53,11 +53,9 @@ POST /we/want/173 HTTP/1.1
User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: %HOSTIP:%HTTPPORT
Accept: */*
-Transfer-Encoding: chunked
-Expect: 100-continue
+Content-Length: 360
Content-Type: multipart/form-data; boundary=----------------------------5dbea401cd8c
-168
------------------------------5dbea401cd8c
Content-Disposition: form-data; name="field1"
@@ -76,9 +74,6 @@ line7
line8
------------------------------5dbea401cd8c--
-
-0
-
</protocol>
</verify>
</testcase>
diff --git a/tests/data/test237 b/tests/data/test237
index 9a40f1f6b..e9147dcd1 100644
--- a/tests/data/test237
+++ b/tests/data/test237
@@ -30,13 +30,9 @@ ftp://%HOSTIP:%FTPPORT/237 --disable-epsv
# certain hosts with buggy resolver code, the resulting address (192.0.2.127)
# is from an address block that is guaranteed never to be assigned (RFC3330).
<verify>
-# curl: (15) Can't resolve new host 1216.256.2.127:32639
-# 15 => CURLE_FTP_CANT_GET_HOST
-# some systems just don't fail on the illegal host name/address but instead
-# moves on and attempt to connect to... yes, to what?
-# 7= CURLE_COULDNT_CONNECT
+# 14 = CURLE_FTP_WEIRD_227_FORMAT
<errorcode>
-15, 7
+14
</errorcode>
<protocol>
USER anonymous
diff --git a/tests/data/test244 b/tests/data/test244
new file mode 100644
index 000000000..8ce4b6346
--- /dev/null
+++ b/tests/data/test244
@@ -0,0 +1,54 @@
+<testcase>
+<info>
+<keywords>
+FTP
+PASV
+CWD
+--ftp-method
+nocwd
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data mode="text">
+total 20
+drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
+drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
+drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
+-r--r--r-- 1 0 1 35 Jul 16 1996 README
+lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
+dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
+drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
+dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
+drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
+dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP dir listing with nocwd and URL encoded path
+ </name>
+ <command>
+--ftp-method nocwd ftp://%HOSTIP:%FTPPORT/fir%23t/th%69rd/244/
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+EPSV
+TYPE A
+LIST fir#t/third/244/
+QUIT
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test298 b/tests/data/test298
index 80913e84b..09b127fbf 100644
--- a/tests/data/test298
+++ b/tests/data/test298
@@ -25,7 +25,7 @@ ftp
FTP CWD with --ftp-method nocwd
</name>
<command>
---ftp-method nocwd ftp://%HOSTIP:%FTPPORT/first/second/third/298
+--ftp-method nocwd ftp://%HOSTIP:%FTPPORT/first/second/th%69rd/298
</command>
</client>
diff --git a/tests/data/test308 b/tests/data/test308
index d20556a19..1a3c8ec53 100644
--- a/tests/data/test308
+++ b/tests/data/test308
@@ -12,6 +12,7 @@ FAILURE
<client>
<features>
OpenSSL
+!MultiSSL
</features>
<server>
https
diff --git a/tests/data/test554 b/tests/data/test554
index ce4a14dc4..24d9c0468 100644
--- a/tests/data/test554
+++ b/tests/data/test554
@@ -68,7 +68,7 @@ s/boundary=------------------------[a-z0-9]*/boundary=--------------------------
POST /554 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
-Content-Length: 718
+Content-Length: 744
Content-Type: multipart/form-data; boundary=----------------------------
------------------------------
@@ -87,6 +87,7 @@ Content-Disposition: form-data; name="filename"
postit2.c
------------------------------
Content-Disposition: form-data; name="submit"
+Content-Type: text/plain
send
------------------------------
@@ -98,7 +99,7 @@ blah blah
POST /554 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
-Content-Length: 732
+Content-Length: 758
Content-Type: multipart/form-data; boundary=----------------------------
------------------------------
@@ -117,6 +118,7 @@ Content-Disposition: form-data; name="filename"
postit2.c
------------------------------
Content-Disposition: form-data; name="submit"
+Content-Type: text/plain
send
------------------------------
diff --git a/tests/data/test577 b/tests/data/test577
new file mode 100644
index 000000000..525549264
--- /dev/null
+++ b/tests/data/test577
@@ -0,0 +1,55 @@
+<testcase>
+
+#Informational
+<info>
+<keywords>
+RTSP
+OPTIONS
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data>
+RTSP/1.1234567 200 OK
+Server: RTSPD/libcurl-test
+CSeq: 1
+Public: DESCRIBE, OPTIONS, SETUP, TEARDOWN, PLAY, PAUSE
+Curl-Private: swsclose
+</data>
+<datacheck>
+</datacheck>
+</reply>
+
+# Client-Side
+<client>
+<server>
+rtsp
+</server>
+<tool>
+lib567
+</tool>
+
+<name>
+Funny RTSP version in response
+</name>
+<command>
+rtsp://%HOSTIP:%RTSPPORT/577
+</command>
+</client>
+
+<verify>
+<protocol>
+OPTIONS rtsp://%HOSTIP:%RTSPPORT/577 RTSP/1.0
+CSeq: 1
+User-Agent: test567
+Test-Number: 567
+
+</protocol>
+# 8 == CURLE_WEIRD_SERVER_REPLY
+<errorcode>
+8
+</errorcode>
+</verify>
+
+</testcase>
diff --git a/tests/data/test587 b/tests/data/test587
index 689a877db..0d9530e93 100644
--- a/tests/data/test587
+++ b/tests/data/test587
@@ -3,6 +3,7 @@
<keywords>
HTTP
HTTP POST
+flaky
</keywords>
</info>
@@ -42,7 +43,7 @@ s/boundary=------------------------[a-z0-9]*/boundary=--------------------------
POST /587 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
-Content-Length: 718
+Content-Length: 744
Content-Type: multipart/form-data; boundary=----------------------------
------------------------------
diff --git a/tests/data/test644 b/tests/data/test644
index 6ac37ce54..4c9a501ed 100644
--- a/tests/data/test644
+++ b/tests/data/test644
@@ -4,6 +4,7 @@
HTTP
HTTP POST
HTTP MIME POST
+flaky
</keywords>
</info>
diff --git a/tests/data/test648 b/tests/data/test648
index cd8f02085..a2b227bcf 100644
--- a/tests/data/test648
+++ b/tests/data/test648
@@ -66,8 +66,8 @@ This is the e-mail inline text with a very long line containing the special=
Content-Disposition: attachment; filename="test648.txt"
Content-Transfer-Encoding: base64
-VGhpcyBpcyBhbiBhdHRhY2hlZCBmaWxlLgoKSXQgbWF5IGNvbnRhaW4gYW55IHR5cGUgb2Yg
-ZGF0YSBhbmQgd2lsbCBiZSBlbmNvZGVkIGluIGJhc2U2NCBmb3IgdHJhbnNmZXIuCg==
+VGhpcyBpcyBhbiBhdHRhY2hlZCBmaWxlLgoKSXQgbWF5IGNvbnRhaW4gYW55IHR5cGUgb2YgZGF0
+YSBhbmQgd2lsbCBiZSBlbmNvZGVkIGluIGJhc2U2NCBmb3IgdHJhbnNmZXIuCg==
--------------------------------
.
</upload>
diff --git a/tests/data/test650 b/tests/data/test650
index e07d4c10b..1a06064c7 100644
--- a/tests/data/test650
+++ b/tests/data/test650
@@ -63,9 +63,12 @@ Transfer-Encoding: chunked
Content-Type: multipart/form-data; boundary=----------------------------
Expect: 100-continue
-5f0
+60a
------------------------------
Content-Disposition: form-data; name="fieldname"
+Content-Type: text/plain
+X-customheader-1: Header 1 data
+X-customheader-2: Header 2 data
this is what we post to the silly web server
------------------------------
@@ -98,15 +101,13 @@ This is data from a file.
------------------------------
Content-Disposition: form-data; name="filecontents"
-X-customheader-1: Header 1 data
-X-customheader-2: Header 2 data
This is data from a file.
------------------------------
Content-Disposition: form-data; name="formlength"
-1341
+1367
------------------------------
Content-Disposition: form-data; name="standardinput"
Content-Type: application/octet-stream
diff --git a/tests/data/test651 b/tests/data/test651
new file mode 100644
index 000000000..b00ca5d0e
--- /dev/null
+++ b/tests/data/test651
@@ -0,0 +1,73 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+FORM
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Connection: close
+Content-Type: text/html
+
+hello
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+# tool is what to use instead of 'curl'
+<tool>
+lib651
+</tool>
+
+ <name>
+curl_formadd with huge COPYCONTENTS
+ </name>
+<stdin>
+ Some data from stdin
+</stdin>
+ <command>
+http://%HOSTIP:%HTTPPORT/651 log/test651.filedata
+</command>
+<file name="log/test651.filedata">
+This is data from a file.
+</file>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strippart>
+s/^--------------------------[a-z0-9]*/------------------------------/
+s/boundary=------------------------[a-z0-9]*/boundary=----------------------------/
+</strippart>
+# Note that the stripping above removes 12 bytes from every occurrence of the
+# boundary string and since 5 of them are in the body contents, we see
+# (5*12) == 60 bytes less
+<protocol>
+POST /651 HTTP/1.1
+Host: 127.0.0.1:8990
+Accept: */*
+Content-Length: 17139
+Content-Type: multipart/form-data; boundary=----------------------------
+Expect: 100-continue
+
+------------------------------
+Content-Disposition: form-data; name="hello"
+
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
+--------------------------------
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test652 b/tests/data/test652
new file mode 100644
index 000000000..c91dcf2fe
--- /dev/null
+++ b/tests/data/test652
@@ -0,0 +1,358 @@
+<testcase>
+<info>
+<keywords>
+SMTP
+MIME
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+smtp
+</server>
+<tool>
+lib652
+</tool>
+
+ <name>
+SMTP with encoded huge mime data contents
+ </name>
+ <command>
+smtp://%HOSTIP:%SMTPPORT/652
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strippart>
+s/^--------------------------[a-z0-9]*/------------------------------/
+s/boundary=------------------------[a-z0-9]*/boundary=----------------------------/
+</strippart>
+<protocol>
+EHLO 652
+MAIL FROM:<somebody@example.com>
+RCPT TO:<someone@example.com>
+DATA
+QUIT
+</protocol>
+<upload>
+Content-Type: multipart/mixed; boundary=----------------------------
+Mime-Version: 1.0
+
+------------------------------
+Content-Disposition: attachment; filename="myfile.jpg"
+Content-Type: image/jpeg
+Content-Transfer-Encoding: base64
+
+QUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZG
+RkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExM
+TExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFS
+UlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dX
+V1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0ND
+Q0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJ
+SUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5O
+Tk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRU
+VFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpa
+WlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVF
+RkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tL
+S0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFR
+UVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZX
+V1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJC
+QkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhI
+SEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5O
+Tk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NT
+U1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZ
+WVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVF
+RUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpK
+S0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQ
+UFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZW
+VlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFC
+QkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dH
+R0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1N
+TU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNT
+U1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhY
+WFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDRERERERE
+REREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpK
+SkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09P
+UFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVV
+VVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFB
+QUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZH
+R0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExM
+TExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJS
+UlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hY
+WFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0ND
+Q0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJ
+SUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09P
+T09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRU
+VVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpa
+WlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZG
+RkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tM
+TExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFR
+UVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dX
+V1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkND
+Q0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhI
+SElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5O
+Tk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRU
+VFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZ
+WlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVF
+RUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tL
+S0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBR
+UVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZW
+VlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJC
+QkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hI
+SEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1N
+TU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NT
+U1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZ
+WVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERE
+RUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpK
+SkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQ
+UFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVW
+VlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFB
+QUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dH
+R0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1N
+TU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJS
+UlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhY
+WFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDRERE
+REREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJ
+SkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09P
+T09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVV
+VVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpB
+QUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZG
+RkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExM
+TExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJS
+UlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dX
+V1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0ND
+Q0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJ
+SUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5O
+T09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRU
+VFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpa
+WlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVG
+RkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tL
+S0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFR
+UVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldX
+V1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJC
+QkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhI
+SEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5O
+Tk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NT
+VFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZ
+WVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVF
+RUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpL
+S0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQ
+UFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZW
+VlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJC
+QkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dH
+R0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1N
+TU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NT
+U1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhY
+WVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERE
+RERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpK
+SkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09Q
+UFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVV
+VVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFB
+QUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdH
+R0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExM
+TE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJS
+UlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhY
+WFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0ND
+REREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJ
+SUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09P
+T09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRV
+VVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpa
+WlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZG
+RkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xM
+TExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFR
+UVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dX
+V1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0ND
+Q0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhI
+SUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5O
+Tk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRU
+VFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVla
+WlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVF
+RUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tL
+S0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFR
+UVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZW
+VldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJC
+QkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhI
+SEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1N
+Tk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NT
+U1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZ
+WVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERF
+RUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpK
+SkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQ
+UFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZW
+VlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFB
+QUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dH
+R0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1N
+TU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJS
+U1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhY
+WFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERE
+RERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlK
+SkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09P
+T09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVV
+VVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFB
+QUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZG
+RkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExM
+TExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJS
+UlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dX
+WFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0ND
+Q0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJ
+SUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5P
+T09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRU
+VFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpa
+WlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZG
+RkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tL
+S0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFR
+UVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dX
+V1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJC
+Q0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhI
+SEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5O
+Tk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NU
+VFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZ
+WVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVF
+RUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktL
+S0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQ
+UFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZW
+VlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJC
+QkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dH
+SEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1N
+TU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NT
+U1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZ
+WVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERE
+RERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpK
+SkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQ
+UFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVV
+VVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFB
+QUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dH
+R0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExM
+TU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJS
+UlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhY
+WFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NE
+RERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJ
+SUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09P
+T09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVV
+VVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpa
+WkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZG
+RkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExM
+TExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFR
+UlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dX
+V1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0ND
+Q0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJ
+SUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5O
+Tk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRU
+VFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpa
+WlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVF
+RUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tL
+S0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFR
+UVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZW
+V1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJC
+QkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhI
+SEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1O
+Tk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NT
+U1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZ
+WVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVF
+RUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpK
+SktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQ
+UFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZW
+VlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFB
+QkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dH
+R0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1N
+TU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJT
+U1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhY
+WFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERE
+RERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpK
+SkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09P
+T1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVV
+VVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFB
+QUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZG
+R0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExM
+TExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJS
+UlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dY
+WFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0ND
+Q0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJ
+SUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9P
+T09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRU
+VFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpa
+WlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZG
+RkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tL
+TExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFR
+UVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dX
+V1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJD
+Q0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhI
+SEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5O
+Tk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RU
+VFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZ
+WVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVF
+RUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tL
+S0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQ
+UVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZW
+VlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJC
+QkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dI
+SEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1N
+TU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NT
+U1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZ
+WVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDRERERERERERE
+REVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpK
+SkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQ
+UFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVV
+VlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFB
+QUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dH
+R0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExN
+TU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJS
+UlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhY
+WFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RE
+RERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJ
+SUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09P
+T09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVV
+VVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpa
+QUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZG
+RkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExM
+TExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFS
+UlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dX
+V1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0ND
+Q0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJ
+SUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5O
+Tk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRU
+VFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpa
+WlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVF
+RkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tL
+S0tLTExMTExMTExMTE1NTU1NTU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFR
+UVFRUVFRUlJSUlJSUlJSUlNTU1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZX
+V1dXV1dXV1dXWFhYWFhYWFhYWFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJC
+QkJDQ0NDQ0NDQ0NDREREREREREREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhI
+SEhISEhJSUlJSUlJSUlJSkpKSkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5O
+Tk5OTk5OTk5PT09PT09PT09PUFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NT
+U1RUVFRUVFRUVFRVVVVVVVVVVVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZ
+WVlZWVpaWlpaWlpaWlpBQUFBQUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVF
+RUVFRUVFRUZGRkZGRkZGRkZHR0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpK
+S0tLS0tLS0tLS0xMTExMTExMTExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQ
+UFBQUVFRUVFRUVFRUVJSUlJSUlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZW
+VlZWVlZWV1dXV1dXV1dXV1hYWFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFC
+QkJCQkJCQkJCQ0NDQ0NDQ0NDQ0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dH
+R0dISEhISEhISEhISUlJSUlJSUlJSUpKSkpKSkpKSkpLS0tLS0tLS0tLTExMTExMTExMTE1NTU1N
+TU1NTU1OTk5OTk5OTk5OT09PT09PT09PT1BQUFBQUFBQUFBRUVFRUVFRUVFRUlJSUlJSUlJSUlNT
+U1NTU1NTU1NUVFRUVFRUVFRUVVVVVVVVVVVVVVZWVlZWVlZWVlZXV1dXV1dXV1dXWFhYWFhYWFhY
+WFlZWVlZWVlZWVlaWlpaWlpaWlpaQUFBQUFBQUFBQUJCQkJCQkJCQkJDQ0NDQ0NDQ0NDRERERERE
+REREREVFRUVFRUVFRUVGRkZGRkZGRkZGR0dHR0dHR0dHR0hISEhISEhISEhJSUlJSUlJSUlJSkpK
+SkpKSkpKSktLS0tLS0tLS0tMTExMTExMTExMTU1NTU1NTU1NTU5OTk5OTk5OTk5PT09PT09PT09P
+UFBQUFBQUFBQUFFRUVFRUVFRUVFSUlJSUlJSUlJSU1NTU1NTU1NTU1RUVFRUVFRUVFRVVVVVVVVV
+VVVVVlZWVlZWVlZWVldXV1dXV1dXV1dYWFhYWFhYWFhYWVlZWVlZWVlZWVpaWlpaWlpaWlpBQUFB
+QUFBQUFBQkJCQkJCQkJCQkNDQ0NDQ0NDQ0NERERERERERERERUVFRUVFRUVFRUZGRkZGRkZGRkZH
+R0dHR0dHR0dHSEhISEhISEhISElJSUlJSUlJSUlKSkpKSkpKSkpKS0tLS0tLS0tLS0xMTExMTExM
+TExNTU1NTU1NTU1NTk5OTk5OTk5OTk9PT09PT09PT09QUFBQUFBQUFBQUVFRUVFRUVFRUVJSUlJS
+UlJSUlJTU1NTU1NTU1NTVFRUVFRUVFRUVFVVVVVVVVVVVVVWVlZWVlZWVlZWV1dXV1dXV1dXV1hY
+WFhYWFhYWFhZWVlZWVlZWVlZWlpaWlpaWlpaWkFBQUFBQUFBQUFCQkJCQkJCQkJCQ0NDQ0NDQ0ND
+Q0RERERERERERERFRUVFRUVFRUVFRkZGRkZGRkZGRkdHR0dHR0dHR0dISEhISEhISEhISUlJSUlJ
+SUlJSUpKSkpKSkpKSko=
+--------------------------------
+.
+</upload>
+</verify>
+</testcase>
diff --git a/tests/data/test653 b/tests/data/test653
new file mode 100644
index 000000000..d620b5761
--- /dev/null
+++ b/tests/data/test653
@@ -0,0 +1,93 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+MIME
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Connection: close
+Content-Type: text/html
+
+hello
+</data>
+<datacheck>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Connection: close
+Content-Type: text/html
+
+hello
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Connection: close
+Content-Type: text/html
+
+hello
+</datacheck>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+# tool is what to use instead of 'curl'
+<tool>
+lib653
+</tool>
+
+ <name>
+Reuse of handle after altering mime data
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/653
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strippart>
+s/^--------------------------[a-z0-9]*/------------------------------/
+s/boundary=------------------------[a-z0-9]*/boundary=----------------------------/
+</strippart>
+# Note that the stripping above removes 12 bytes from every occurrence of the
+# boundary string and since 5 of them are in the body contents, we see
+# (5*12) == 60 bytes less
+<protocol>
+POST /653 HTTP/1.1
+Host: 127.0.0.1:8990
+Accept: */*
+Content-Length: 150
+Content-Type: multipart/form-data; boundary=----------------------------
+
+------------------------------
+Content-Disposition: form-data; name="name"
+
+short value
+--------------------------------
+POST /653 HTTP/1.1
+Host: 127.0.0.1:8990
+Accept: */*
+Content-Length: 167
+Content-Type: multipart/form-data; boundary=----------------------------
+
+------------------------------
+Content-Disposition: form-data; name="name"
+
+long value for length change
+--------------------------------
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test950 b/tests/data/test950
new file mode 100644
index 000000000..295f8b877
--- /dev/null
+++ b/tests/data/test950
@@ -0,0 +1,43 @@
+<testcase>
+<info>
+<keywords>
+SMTP
+VRFY
+--request
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+250 <recipient@example.com>
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+smtp
+</server>
+ <name>
+SMTP VRFY with custom request
+ </name>
+
+# the custom request just does it lowercase to remain the same command
+<command>
+smtp://%HOSTIP:%SMTPPORT/950 --mail-rcpt recipient --request "vrfy"
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+EHLO 950
+vrfy recipient
+QUIT
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl
index 2aba4263a..ae8b4a017 100755
--- a/tests/ftpserver.pl
+++ b/tests/ftpserver.pl
@@ -3023,7 +3023,7 @@ while(1) {
undef $ftplistparserstate;
}
if($ftptargetdir) {
- undef $ftptargetdir;
+ $ftptargetdir = "";
}
if($verbose) {
@@ -3193,7 +3193,7 @@ while(1) {
}
# only perform this if we're not faking a reply
- my $func = $commandfunc{$FTPCMD};
+ my $func = $commandfunc{uc($FTPCMD)};
if($func) {
&$func($FTPARG, $FTPCMD);
$check = 0;
diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am
deleted file mode 100644
index dcea6d576..000000000
--- a/tests/fuzz/Makefile.am
+++ /dev/null
@@ -1,56 +0,0 @@
-#***************************************************************************
-# _ _ ____ _
-# Project ___| | | | _ \| |
-# / __| | | | |_) | |
-# | (__| |_| | _ <| |___
-# \___|\___/|_| \_\_____|
-#
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
-#
-# This software is licensed as described in the file COPYING, which
-# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
-#
-# You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# copies of the Software, and permit persons to whom the Software is
-# furnished to do so, under the terms of the COPYING file.
-#
-# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# KIND, either express or implied.
-#
-###########################################################################
-AUTOMAKE_OPTIONS = foreign nostdinc
-
-# Specify our include paths here, and do it relative to $(top_srcdir) and
-# $(top_builddir), to ensure that these paths which belong to the library
-# being currently built and tested are searched before the library which
-# might possibly already be installed in the system.
-#
-# $(top_srcdir)/include is for libcurl's external include files
-# $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file
-# $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "borrowed" files
-
-AM_CXXFLAGS = -I$(top_srcdir)/include \
- -I$(top_builddir)/lib \
- -I$(top_srcdir)/lib \
- -I$(top_srcdir)/tests/fuzz
-
-LIBS = -lpthread -lm
-
-# Run e.g. "make all LIB_FUZZING_ENGINE=/path/to/libFuzzer.a"
-# to link the fuzzer(s) against a real fuzzing engine.
-#
-# OSS-Fuzz will define its own value for LIB_FUZZING_ENGINE.
-LIB_FUZZING_ENGINE ?= libstandaloneengine.a
-
-LDADD = $(top_builddir)/lib/libgnurl.la \
- $(LIB_FUZZING_ENGINE) @LDFLAGS@ @LIBCURL_LIBS@
-
-# Makefile.inc provides neat definitions
-include Makefile.inc
-
-checksrc:
- @PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.cc
-
-noinst_PROGRAMS = $(FUZZPROGS)
-noinst_LIBRARIES = $(FUZZLIBS)
diff --git a/tests/fuzz/Makefile.inc b/tests/fuzz/Makefile.inc
deleted file mode 100644
index f52adb89c..000000000
--- a/tests/fuzz/Makefile.inc
+++ /dev/null
@@ -1,15 +0,0 @@
-FUZZPROGS = curl_fuzzer
-FUZZLIBS = libstandaloneengine.a
-
-curl_fuzzer_SOURCES = curl_fuzzer.cc
-curl_fuzzer_CXXFLAGS = $(AM_CXXFLAGS)
-
-libstandaloneengine_a_SOURCES = standalone_fuzz_target_runner.cc
-libstandaloneengine_a_CXXFLAGS = $(AM_CXXFLAGS)
-
-# Some more targets.
-zip:
- zip -q -r curl_fuzzer_seed_corpus.zip curl_fuzz_data
-
-check: all
- ./curl_fuzzer curl_fuzz_data/*
diff --git a/tests/fuzz/README b/tests/fuzz/README
index 8b5fcd011..c19e04fbe 100644
--- a/tests/fuzz/README
+++ b/tests/fuzz/README
@@ -1,21 +1,8 @@
Fuzz tests
==========
-The goal is to add tests for *ALL* protocols supported in libcurl.
+The fuzzing tests for curl have been moved to a separate repository:
-Building the fuzz target
-========================
-From the CURL root directory:
+https://github.com/curl/curl-fuzzer
-export CC=clang-5.0
-export CXX=clang++-5.0
-export CFLAGS="-fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp"
-export CXXFLAGS="-fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp -stdlib=libc++"
-./configure --disable-shared --enable-debug --enable-maintainer-mode
-make -sj
-
-cd tests/fuzz
-
-(optional) export LIB_FUZZING_ENGINE=<path to libFuzzer.a>
-
-make check
+More information on how to get started with curl fuzz testing can be found there.
diff --git a/tests/fuzz/corpus.py b/tests/fuzz/corpus.py
deleted file mode 100644
index 5474c99af..000000000
--- a/tests/fuzz/corpus.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-#
-# Common corpus functions
-import logging
-import struct
-log = logging.getLogger(__name__)
-
-
-class BaseType(object):
- TYPE_URL = 1
- TYPE_RSP1 = 2
- TYPE_USERNAME = 3
- TYPE_PASSWORD = 4
- TYPE_POSTFIELDS = 5
- TYPE_HEADER = 6
- TYPE_COOKIE = 7
- TYPE_UPLOAD1 = 8
- TYPE_RANGE = 9
- TYPE_CUSTOMREQUEST = 10
- TYPE_MAIL_RECIPIENT = 11
- TYPE_MAIL_FROM = 12
-
-
-class TLVEncoder(BaseType):
- def __init__(self, output):
- self.output = output
-
- def write_string(self, tlv_type, wstring):
- data = wstring.encode("utf-8")
- self.write_tlv(tlv_type, len(data), data)
-
- def write_bytes(self, tlv_type, bytedata):
- self.write_tlv(tlv_type, len(bytedata), bytedata)
-
- def maybe_write_string(self, tlv_type, wstring):
- if wstring is not None:
- self.write_string(tlv_type, wstring)
-
- def write_tlv(self, tlv_type, tlv_length, tlv_data=None):
- log.debug("Writing TLV %d, length %d, data %r",
- tlv_type,
- tlv_length,
- tlv_data)
-
- data = struct.pack("!H", tlv_type)
- self.output.write(data)
-
- data = struct.pack("!L", tlv_length)
- self.output.write(data)
-
- if tlv_data:
- self.output.write(tlv_data)
-
-
-class TLVDecoder(BaseType):
- def __init__(self, inputdata):
- self.inputdata = inputdata
- self.pos = 0
- self.tlv = None
-
- def __iter__(self):
- self.pos = 0
- self.tlv = None
- return self
-
- def __next__(self):
- if self.tlv:
- self.pos += self.tlv.total_length()
-
- if (self.pos + TLVHeader.TLV_DECODE_FMT_LEN) > len(self.inputdata):
- raise StopIteration
-
- # Get the next TLV
- self.tlv = TLVHeader(self.inputdata[self.pos:])
- return self.tlv
-
- next = __next__
-
-
-class TLVHeader(BaseType):
- TLV_DECODE_FMT = "!HL"
- TLV_DECODE_FMT_LEN = struct.calcsize(TLV_DECODE_FMT)
-
- def __init__(self, data):
- # Parse the data to populate the TLV fields
- (self.type, self.length) = struct.unpack(self.TLV_DECODE_FMT, data[0:self.TLV_DECODE_FMT_LEN])
-
- # Get the remaining data and store it.
- self.data = data[self.TLV_DECODE_FMT_LEN:self.TLV_DECODE_FMT_LEN + self.length]
-
- def __repr__(self):
- return ("{self.__class__.__name__}(type={self.type!r}, length={self.length!r}, data={self.data!r})"
- .format(self=self))
-
- def total_length(self):
- return self.TLV_DECODE_FMT_LEN + self.length \ No newline at end of file
diff --git a/tests/fuzz/curl_fuzz_data/oss-fuzz-3327 b/tests/fuzz/curl_fuzz_data/oss-fuzz-3327
deleted file mode 100644
index 064cc623a..000000000
--- a/tests/fuzz/curl_fuzz_data/oss-fuzz-3327
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test1 b/tests/fuzz/curl_fuzz_data/test1
deleted file mode 100644
index f7b734a9c..000000000
--- a/tests/fuzz/curl_fuzz_data/test1
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test10 b/tests/fuzz/curl_fuzz_data/test10
deleted file mode 100644
index af1ed53ca..000000000
--- a/tests/fuzz/curl_fuzz_data/test10
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test100 b/tests/fuzz/curl_fuzz_data/test100
deleted file mode 100644
index b58d9335a..000000000
--- a/tests/fuzz/curl_fuzz_data/test100
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test12 b/tests/fuzz/curl_fuzz_data/test12
deleted file mode 100644
index 9ad91dc07..000000000
--- a/tests/fuzz/curl_fuzz_data/test12
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test13 b/tests/fuzz/curl_fuzz_data/test13
deleted file mode 100644
index 448077dde..000000000
--- a/tests/fuzz/curl_fuzz_data/test13
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test1326 b/tests/fuzz/curl_fuzz_data/test1326
deleted file mode 100644
index 8801fac96..000000000
--- a/tests/fuzz/curl_fuzz_data/test1326
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test1450 b/tests/fuzz/curl_fuzz_data/test1450
deleted file mode 100644
index 601236168..000000000
--- a/tests/fuzz/curl_fuzz_data/test1450
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test2 b/tests/fuzz/curl_fuzz_data/test2
deleted file mode 100644
index 8b44d6719..000000000
--- a/tests/fuzz/curl_fuzz_data/test2
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test271 b/tests/fuzz/curl_fuzz_data/test271
deleted file mode 100644
index 3a26767f7..000000000
--- a/tests/fuzz/curl_fuzz_data/test271
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test3 b/tests/fuzz/curl_fuzz_data/test3
deleted file mode 100644
index 81c6670aa..000000000
--- a/tests/fuzz/curl_fuzz_data/test3
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test4 b/tests/fuzz/curl_fuzz_data/test4
deleted file mode 100644
index 3fa395a29..000000000
--- a/tests/fuzz/curl_fuzz_data/test4
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test5 b/tests/fuzz/curl_fuzz_data/test5
deleted file mode 100644
index bdaac4e66..000000000
--- a/tests/fuzz/curl_fuzz_data/test5
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test6 b/tests/fuzz/curl_fuzz_data/test6
deleted file mode 100644
index 98d9be216..000000000
--- a/tests/fuzz/curl_fuzz_data/test6
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test800 b/tests/fuzz/curl_fuzz_data/test800
deleted file mode 100644
index a5899be43..000000000
--- a/tests/fuzz/curl_fuzz_data/test800
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test850 b/tests/fuzz/curl_fuzz_data/test850
deleted file mode 100644
index 22c08dcfc..000000000
--- a/tests/fuzz/curl_fuzz_data/test850
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzz_data/test900 b/tests/fuzz/curl_fuzz_data/test900
deleted file mode 100644
index eecf0cbaf..000000000
--- a/tests/fuzz/curl_fuzz_data/test900
+++ /dev/null
Binary files differ
diff --git a/tests/fuzz/curl_fuzzer.cc b/tests/fuzz/curl_fuzzer.cc
deleted file mode 100644
index dd0298f36..000000000
--- a/tests/fuzz/curl_fuzzer.cc
+++ /dev/null
@@ -1,447 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2017, Max Dymond, <cmeister2@gmail.com>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <curl/curl.h>
-#include "curl_fuzzer.h"
-
-/**
- * Fuzzing entry point. This function is passed a buffer containing a test
- * case. This test case should drive the CURL API into making a request.
- */
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
-{
- int rc = 0;
- int tlv_rc;
- FUZZ_DATA fuzz;
- TLV tlv;
-
- /* Have to set all fields to zero before getting to the terminate function */
- memset(&fuzz, 0, sizeof(FUZZ_DATA));
-
- if(size < sizeof(TLV_RAW)) {
- /* Not enough data for a single TLV - don't continue */
- goto EXIT_LABEL;
- }
-
- /* Try to initialize the fuzz data */
- FTRY(fuzz_initialize_fuzz_data(&fuzz, data, size));
-
- for(tlv_rc = fuzz_get_first_tlv(&fuzz, &tlv);
- tlv_rc == 0;
- tlv_rc = fuzz_get_next_tlv(&fuzz, &tlv)) {
-
- /* Have the TLV in hand. Parse the TLV. */
- rc = fuzz_parse_tlv(&fuzz, &tlv);
-
- if(rc != 0) {
- /* Failed to parse the TLV. Can't continue. */
- goto EXIT_LABEL;
- }
- }
-
- if(tlv_rc != TLV_RC_NO_MORE_TLVS) {
- /* A TLV call failed. Can't continue. */
- goto EXIT_LABEL;
- }
-
- /* Do the CURL stuff! */
- if(fuzz.header_list != NULL) {
- curl_easy_setopt(fuzz.easy, CURLOPT_HTTPHEADER, fuzz.header_list);
- }
-
- if(fuzz.mail_recipients_list != NULL) {
- curl_easy_setopt(fuzz.easy, CURLOPT_MAIL_RCPT, fuzz.mail_recipients_list);
- }
-
- curl_easy_perform(fuzz.easy);
-
-EXIT_LABEL:
-
- fuzz_terminate_fuzz_data(&fuzz);
-
- /* This function must always return 0. Non-zero codes are reserved. */
- return 0;
-}
-
-/**
- * Utility function to convert 4 bytes to a u32 predictably.
- */
-uint32_t to_u32(uint8_t b[4])
-{
- uint32_t u;
- u = (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3];
- return u;
-}
-
-/**
- * Utility function to convert 2 bytes to a u16 predictably.
- */
-uint16_t to_u16(uint8_t b[2])
-{
- uint16_t u;
- u = (b[0] << 8) + b[1];
- return u;
-}
-
-/**
- * Initialize the local fuzz data structure.
- */
-int fuzz_initialize_fuzz_data(FUZZ_DATA *fuzz,
- const uint8_t *data,
- size_t data_len)
-{
- int rc = 0;
-
- /* Initialize the fuzz data. */
- memset(fuzz, 0, sizeof(FUZZ_DATA));
-
- /* Create an easy handle. This will have all of the settings configured on
- it. */
- fuzz->easy = curl_easy_init();
- FCHECK(fuzz->easy != NULL);
-
- /* Set some standard options on the CURL easy handle. We need to override the
- socket function so that we create our own sockets to present to CURL. */
- FTRY(curl_easy_setopt(fuzz->easy,
- CURLOPT_OPENSOCKETFUNCTION,
- fuzz_open_socket));
- FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_OPENSOCKETDATA, fuzz));
-
- /* In case something tries to set a socket option, intercept this. */
- FTRY(curl_easy_setopt(fuzz->easy,
- CURLOPT_SOCKOPTFUNCTION,
- fuzz_sockopt_callback));
-
- /* Set the standard read function callback. */
- FTRY(curl_easy_setopt(fuzz->easy,
- CURLOPT_READFUNCTION,
- fuzz_read_callback));
- FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_READDATA, fuzz));
-
- /* Set the standard write function callback. */
- FTRY(curl_easy_setopt(fuzz->easy,
- CURLOPT_WRITEFUNCTION,
- fuzz_write_callback));
- FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_WRITEDATA, fuzz));
-
- /* Can enable verbose mode by changing 0L to 1L */
- FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_VERBOSE, 0L));
-
- /* Set up the state parser */
- fuzz->state.data = data;
- fuzz->state.data_len = data_len;
-
-EXIT_LABEL:
-
- return rc;
-}
-
-/**
- * Terminate the fuzz data structure, including freeing any allocated memory.
- */
-void fuzz_terminate_fuzz_data(FUZZ_DATA *fuzz)
-{
- fuzz_free((void **)&fuzz->url);
- fuzz_free((void **)&fuzz->username);
- fuzz_free((void **)&fuzz->password);
- fuzz_free((void **)&fuzz->postfields);
- fuzz_free((void **)&fuzz->cookie);
- fuzz_free((void **)&fuzz->range);
- fuzz_free((void **)&fuzz->customrequest);
- fuzz_free((void **)&fuzz->mail_from);
-
- if(fuzz->header_list != NULL) {
- curl_slist_free_all(fuzz->header_list);
- fuzz->header_list = NULL;
- }
-
- if(fuzz->mail_recipients_list != NULL) {
- curl_slist_free_all(fuzz->mail_recipients_list);
- fuzz->mail_recipients_list = NULL;
- }
-
- if(fuzz->easy != NULL) {
- curl_easy_cleanup(fuzz->easy);
- fuzz->easy = NULL;
- }
-}
-
-/**
- * If a pointer has been allocated, free that pointer.
- */
-void fuzz_free(void **ptr)
-{
- if(*ptr != NULL) {
- free(*ptr);
- *ptr = NULL;
- }
-}
-
-/**
- * Function for providing a socket to CURL already primed with data.
- */
-static curl_socket_t fuzz_open_socket(void *ptr,
- curlsocktype purpose,
- struct curl_sockaddr *address)
-{
- FUZZ_DATA *fuzz = (FUZZ_DATA *)ptr;
- int fds[2];
- curl_socket_t server_fd;
- curl_socket_t client_fd;
-
- /* Handle unused parameters */
- (void)purpose;
- (void)address;
-
- if(socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) {
- /* Failed to create a pair of sockets. */
- return CURL_SOCKET_BAD;
- }
-
- server_fd = fds[0];
- client_fd = fds[1];
-
- /* Try and write the response data to the server file descriptor so the
- client can read it. */
- if(write(server_fd,
- fuzz->rsp1_data,
- fuzz->rsp1_data_len) != (ssize_t)fuzz->rsp1_data_len) {
- /* Failed to write the data. */
- return CURL_SOCKET_BAD;
- }
-
- if(shutdown(server_fd, SHUT_WR)) {
- return CURL_SOCKET_BAD;
- }
-
- return client_fd;
-}
-
-/**
- * Callback function for setting socket options on the sockets created by
- * fuzz_open_socket. In our testbed the sockets are "already connected".
- */
-static int fuzz_sockopt_callback(void *ptr,
- curl_socket_t curlfd,
- curlsocktype purpose)
-{
- (void)ptr;
- (void)curlfd;
- (void)purpose;
-
- return CURL_SOCKOPT_ALREADY_CONNECTED;
-}
-
-/**
- * Callback function for doing data uploads.
- */
-static size_t fuzz_read_callback(char *buffer,
- size_t size,
- size_t nitems,
- void *ptr)
-{
- FUZZ_DATA *fuzz = (FUZZ_DATA *)ptr;
- curl_off_t nread;
-
- /* If no upload data has been specified, then return an error code. */
- if(fuzz->upload1_data_len == 0) {
- /* No data to upload */
- return CURL_READFUNC_ABORT;
- }
-
- /* Send the upload data. */
- memcpy(buffer,
- fuzz->upload1_data,
- fuzz->upload1_data_len);
-
- return fuzz->upload1_data_len;
-}
-
-/**
- * Callback function for handling data output quietly.
- */
-static size_t fuzz_write_callback(void *contents,
- size_t size,
- size_t nmemb,
- void *ptr)
-{
- size_t total = size * nmemb;
- FUZZ_DATA *fuzz = (FUZZ_DATA *)ptr;
- size_t copy_len = total;
-
- /* Restrict copy_len to at most TEMP_WRITE_ARRAY_SIZE. */
- if(copy_len > TEMP_WRITE_ARRAY_SIZE) {
- copy_len = TEMP_WRITE_ARRAY_SIZE;
- }
-
- /* Copy bytes to the temp store just to ensure the parameters are
- exercised. */
- memcpy(fuzz->write_array, contents, copy_len);
-
- return total;
-}
-
-/**
- * TLV access function - gets the first TLV from a data stream.
- */
-int fuzz_get_first_tlv(FUZZ_DATA *fuzz,
- TLV *tlv)
-{
- /* Reset the cursor. */
- fuzz->state.data_pos = 0;
- return fuzz_get_tlv_comn(fuzz, tlv);
-}
-
-/**
- * TLV access function - gets the next TLV from a data stream.
-*/
-int fuzz_get_next_tlv(FUZZ_DATA *fuzz,
- TLV *tlv)
-{
- /* Advance the cursor by the full length of the previous TLV. */
- fuzz->state.data_pos += sizeof(TLV_RAW) + tlv->length;
-
- /* Work out if there's a TLV's worth of data to read */
- if(fuzz->state.data_pos + sizeof(TLV_RAW) > fuzz->state.data_len) {
- /* No more TLVs to parse */
- return TLV_RC_NO_MORE_TLVS;
- }
-
- return fuzz_get_tlv_comn(fuzz, tlv);
-}
-
-/**
- * Common TLV function for accessing TLVs in a data stream.
- */
-int fuzz_get_tlv_comn(FUZZ_DATA *fuzz,
- TLV *tlv)
-{
- int rc = 0;
- size_t data_offset;
- TLV_RAW *raw;
-
- /* Start by casting the data stream to a TLV. */
- raw = (TLV_RAW *)&fuzz->state.data[fuzz->state.data_pos];
- data_offset = fuzz->state.data_pos + sizeof(TLV_RAW);
-
- /* Set the TLV values. */
- tlv->type = to_u16(raw->raw_type);
- tlv->length = to_u32(raw->raw_length);
- tlv->value = &fuzz->state.data[data_offset];
-
- /* Sanity check that the TLV length is ok. */
- if(data_offset + tlv->length > fuzz->state.data_len) {
- rc = TLV_RC_SIZE_ERROR;
- }
-
- return rc;
-}
-
-/**
- * Do different actions on the CURL handle for different received TLVs.
- */
-int fuzz_parse_tlv(FUZZ_DATA *fuzz, TLV *tlv)
-{
- int rc;
- char *tmp;
-
- switch(tlv->type) {
- case TLV_TYPE_RESPONSE1:
- /* The pointers in the TLV will always be valid as long as the fuzz data
- is in scope, which is the entirety of this file. */
- fuzz->rsp1_data = tlv->value;
- fuzz->rsp1_data_len = tlv->length;
- break;
-
- case TLV_TYPE_UPLOAD1:
- /* The pointers in the TLV will always be valid as long as the fuzz data
- is in scope, which is the entirety of this file. */
- fuzz->upload1_data = tlv->value;
- fuzz->upload1_data_len = tlv->length;
-
- curl_easy_setopt(fuzz->easy, CURLOPT_UPLOAD, 1L);
- curl_easy_setopt(fuzz->easy,
- CURLOPT_INFILESIZE_LARGE,
- (curl_off_t)fuzz->upload1_data_len);
- break;
-
- case TLV_TYPE_HEADER:
- tmp = fuzz_tlv_to_string(tlv);
- fuzz->header_list = curl_slist_append(fuzz->header_list, tmp);
- fuzz_free((void **)&tmp);
- break;
-
- case TLV_TYPE_MAIL_RECIPIENT:
- tmp = fuzz_tlv_to_string(tlv);
- fuzz->mail_recipients_list =
- curl_slist_append(fuzz->mail_recipients_list, tmp);
- fuzz_free((void **)&tmp);
- break;
-
- /* Define a set of singleton TLVs - they can only have their value set once
- and all follow the same pattern. */
- FSINGLETONTLV(TLV_TYPE_URL, url, CURLOPT_URL);
- FSINGLETONTLV(TLV_TYPE_USERNAME, username, CURLOPT_USERNAME);
- FSINGLETONTLV(TLV_TYPE_PASSWORD, password, CURLOPT_PASSWORD);
- FSINGLETONTLV(TLV_TYPE_POSTFIELDS, postfields, CURLOPT_POSTFIELDS);
- FSINGLETONTLV(TLV_TYPE_COOKIE, cookie, CURLOPT_COOKIE);
- FSINGLETONTLV(TLV_TYPE_RANGE, range, CURLOPT_RANGE);
- FSINGLETONTLV(TLV_TYPE_CUSTOMREQUEST, customrequest, CURLOPT_CUSTOMREQUEST);
- FSINGLETONTLV(TLV_TYPE_MAIL_FROM, mail_from, CURLOPT_MAIL_FROM);
-
- default:
- /* The fuzzer generates lots of unknown TLVs - we don't want these in the
- corpus so we reject any unknown TLVs. */
- rc = 255;
- goto EXIT_LABEL;
- break;
- }
-
- rc = 0;
-
-EXIT_LABEL:
-
- return rc;
-}
-
-/**
- * Converts a TLV data and length into an allocated string.
- */
-char *fuzz_tlv_to_string(TLV *tlv)
-{
- char *tlvstr;
-
- /* Allocate enough space, plus a null terminator */
- tlvstr = (char *)malloc(tlv->length + 1);
-
- if(tlvstr != NULL) {
- memcpy(tlvstr, tlv->value, tlv->length);
- tlvstr[tlv->length] = 0;
- }
-
- return tlvstr;
-}
diff --git a/tests/fuzz/curl_fuzzer.h b/tests/fuzz/curl_fuzzer.h
deleted file mode 100644
index 219ac3ee3..000000000
--- a/tests/fuzz/curl_fuzzer.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2017, Max Dymond, <cmeister2@gmail.com>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include <curl/curl.h>
-#include <testinput.h>
-
-/**
- * TLV types.
- */
-#define TLV_TYPE_URL 1
-#define TLV_TYPE_RESPONSE1 2
-#define TLV_TYPE_USERNAME 3
-#define TLV_TYPE_PASSWORD 4
-#define TLV_TYPE_POSTFIELDS 5
-#define TLV_TYPE_HEADER 6
-#define TLV_TYPE_COOKIE 7
-#define TLV_TYPE_UPLOAD1 8
-#define TLV_TYPE_RANGE 9
-#define TLV_TYPE_CUSTOMREQUEST 10
-#define TLV_TYPE_MAIL_RECIPIENT 11
-#define TLV_TYPE_MAIL_FROM 12
-
-/**
- * TLV function return codes.
- */
-#define TLV_RC_NO_ERROR 0
-#define TLV_RC_NO_MORE_TLVS 1
-#define TLV_RC_SIZE_ERROR 2
-
-/* Temporary write array size */
-#define TEMP_WRITE_ARRAY_SIZE 10
-
-/**
- * Byte stream representation of the TLV header. Casting the byte stream
- * to a TLV_RAW allows us to examine the type and length.
- */
-typedef struct tlv_raw
-{
- /* Type of the TLV - 16 bits. */
- uint8_t raw_type[2];
-
- /* Length of the TLV data - 32 bits. */
- uint8_t raw_length[4];
-
-} TLV_RAW;
-
-typedef struct tlv
-{
- /* Type of the TLV */
- uint16_t type;
-
- /* Length of the TLV data */
- uint32_t length;
-
- /* Pointer to data if length > 0. */
- const uint8_t *value;
-
-} TLV;
-
-/**
- * Internal state when parsing a TLV data stream.
- */
-typedef struct fuzz_parse_state
-{
- /* Data stream */
- const uint8_t *data;
- size_t data_len;
-
- /* Current position of our "cursor" in processing the data stream. */
- size_t data_pos;
-
-} FUZZ_PARSE_STATE;
-
-/**
- * Data local to a fuzzing run.
- */
-typedef struct fuzz_data
-{
- /* CURL easy object */
- CURL *easy;
-
- /* Parser state */
- FUZZ_PARSE_STATE state;
-
- /* Temporary writefunction state */
- char write_array[TEMP_WRITE_ARRAY_SIZE];
-
- /* Response data and length */
- const uint8_t *rsp1_data;
- size_t rsp1_data_len;
-
- /* Upload data and length; */
- const uint8_t *upload1_data;
- size_t upload1_data_len;
-
- /* Singleton string fields. */
- char *url;
- char *username;
- char *password;
- char *postfields;
- char *cookie;
- char *range;
- char *customrequest;
- char *mail_from;
-
- /* List of headers */
- struct curl_slist *header_list;
-
- /* List of mail recipients */
- struct curl_slist *mail_recipients_list;
-
-} FUZZ_DATA;
-
-/* Function prototypes */
-uint32_t to_u32(uint8_t b[4]);
-uint16_t to_u16(uint8_t b[2]);
-int fuzz_initialize_fuzz_data(FUZZ_DATA *fuzz,
- const uint8_t *data,
- size_t data_len);
-void fuzz_terminate_fuzz_data(FUZZ_DATA *fuzz);
-void fuzz_free(void **ptr);
-static curl_socket_t fuzz_open_socket(void *ptr,
- curlsocktype purpose,
- struct curl_sockaddr *address);
-static int fuzz_sockopt_callback(void *ptr,
- curl_socket_t curlfd,
- curlsocktype purpose);
-static size_t fuzz_read_callback(char *buffer,
- size_t size,
- size_t nitems,
- void *ptr);
-static size_t fuzz_write_callback(void *contents,
- size_t size,
- size_t nmemb,
- void *ptr);
-int fuzz_get_first_tlv(FUZZ_DATA *fuzz, TLV *tlv);
-int fuzz_get_next_tlv(FUZZ_DATA *fuzz, TLV *tlv);
-int fuzz_get_tlv_comn(FUZZ_DATA *fuzz, TLV *tlv);
-int fuzz_parse_tlv(FUZZ_DATA *fuzz, TLV *tlv);
-char *fuzz_tlv_to_string(TLV *tlv);
-
-/* Macros */
-#define FTRY(FUNC) \
- { \
- int _func_rc = (FUNC); \
- if (_func_rc) \
- { \
- rc = _func_rc; \
- goto EXIT_LABEL; \
- } \
- }
-
-#define FCHECK(COND) \
- { \
- if (!(COND)) \
- { \
- rc = 255; \
- goto EXIT_LABEL; \
- } \
- }
-
-#define FSINGLETONTLV(TLVNAME, FIELDNAME, OPTNAME) \
- case TLVNAME: \
- FCHECK(fuzz->FIELDNAME == NULL); \
- fuzz->FIELDNAME = fuzz_tlv_to_string(tlv); \
- FTRY(curl_easy_setopt(fuzz->easy, OPTNAME, fuzz->FIELDNAME)); \
- break \ No newline at end of file
diff --git a/tests/fuzz/download_fuzzer.sh b/tests/fuzz/download_fuzzer.sh
new file mode 100755
index 000000000..28228e004
--- /dev/null
+++ b/tests/fuzz/download_fuzzer.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# If any commands fail, fail the script immediately.
+set -ex
+
+# Clone the curl-fuzzer repository to the specified directory.
+git clone http://github.com/curl/curl-fuzzer $1
+
diff --git a/tests/fuzz/generate_corpus.py b/tests/fuzz/generate_corpus.py
deleted file mode 100755
index cffdd37bf..000000000
--- a/tests/fuzz/generate_corpus.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python
-#
-# Simple script which generates corpus files.
-
-import argparse
-import logging
-import corpus
-import sys
-sys.path.append("..")
-import curl_test_data
-log = logging.getLogger(__name__)
-
-
-def generate_corpus(options):
- td = curl_test_data.TestData("../data")
-
- with open(options.output, "wb") as f:
- enc = corpus.TLVEncoder(f)
-
- # Write the URL to the file.
- enc.write_string(enc.TYPE_URL, options.url)
-
- # Write the first response to the file.
- if options.rsp1:
- enc.write_bytes(enc.TYPE_RSP1, options.rsp1.encode("utf-8"))
-
- elif options.rsp1file:
- with open(options.rsp1file, "rb") as g:
- enc.write_bytes(enc.TYPE_RSP1, g.read())
-
- elif options.rsp1test:
- wstring = td.get_test_data(options.rsp1test)
- enc.write_bytes(enc.TYPE_RSP1, wstring.encode("utf-8"))
-
- # Write other options to file.
- enc.maybe_write_string(enc.TYPE_USERNAME, options.username)
- enc.maybe_write_string(enc.TYPE_PASSWORD, options.password)
- enc.maybe_write_string(enc.TYPE_POSTFIELDS, options.postfields)
- enc.maybe_write_string(enc.TYPE_COOKIE, options.cookie)
- enc.maybe_write_string(enc.TYPE_RANGE, options.range)
- enc.maybe_write_string(enc.TYPE_CUSTOMREQUEST, options.customrequest)
- enc.maybe_write_string(enc.TYPE_MAIL_FROM, options.mailfrom)
-
- # Write the first upload to the file.
- if options.upload1:
- enc.write_bytes(enc.TYPE_UPLOAD1, options.upload1.encode("utf-8"))
- elif options.upload1file:
- with open(options.upload1file, "rb") as g:
- enc.write_bytes(enc.TYPE_UPLOAD1, g.read())
-
- # Write an array of headers to the file.
- if options.header:
- for header in options.header:
- enc.write_string(enc.TYPE_HEADER, header)
-
- # Write an array of headers to the file.
- if options.mailrecipient:
- for mailrecipient in options.mailrecipient:
- enc.write_string(enc.TYPE_MAIL_RECIPIENT, mailrecipient)
-
- return ScriptRC.SUCCESS
-
-
-def get_options():
- parser = argparse.ArgumentParser()
- parser.add_argument("--output", required=True)
- parser.add_argument("--url", required=True)
- parser.add_argument("--username")
- parser.add_argument("--password")
- parser.add_argument("--postfields")
- parser.add_argument("--header", action="append")
- parser.add_argument("--cookie")
- parser.add_argument("--range")
- parser.add_argument("--customrequest")
- parser.add_argument("--mailfrom")
- parser.add_argument("--mailrecipient", action="append")
-
- rsp1 = parser.add_mutually_exclusive_group(required=True)
- rsp1.add_argument("--rsp1")
- rsp1.add_argument("--rsp1file")
- rsp1.add_argument("--rsp1test", type=int)
-
- upload1 = parser.add_mutually_exclusive_group()
- upload1.add_argument("--upload1")
- upload1.add_argument("--upload1file")
-
- return parser.parse_args()
-
-
-def setup_logging():
- """
- Set up logging from the command line options
- """
- root_logger = logging.getLogger()
- formatter = logging.Formatter("%(asctime)s %(levelname)-5.5s %(message)s")
- stdout_handler = logging.StreamHandler(sys.stdout)
- stdout_handler.setFormatter(formatter)
- stdout_handler.setLevel(logging.DEBUG)
- root_logger.addHandler(stdout_handler)
- root_logger.setLevel(logging.DEBUG)
-
-
-class ScriptRC(object):
- """Enum for script return codes"""
- SUCCESS = 0
- FAILURE = 1
- EXCEPTION = 2
-
-
-class ScriptException(Exception):
- pass
-
-
-def main():
- # Get the options from the user.
- options = get_options()
-
- setup_logging()
-
- # Run main script.
- try:
- rc = generate_corpus(options)
- except Exception as e:
- log.exception(e)
- rc = ScriptRC.EXCEPTION
-
- log.info("Returning %d", rc)
- return rc
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/tests/fuzz/read_corpus.py b/tests/fuzz/read_corpus.py
deleted file mode 100755
index bb8fcedcd..000000000
--- a/tests/fuzz/read_corpus.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/env python
-#
-# Simple script which reads corpus files.
-
-import argparse
-import logging
-import sys
-import corpus
-log = logging.getLogger(__name__)
-
-
-def read_corpus(options):
- with open(options.input, "rb") as f:
- dec = corpus.TLVDecoder(f.read())
- for tlv in dec:
- print(tlv)
-
- return ScriptRC.SUCCESS
-
-
-def get_options():
- parser = argparse.ArgumentParser()
- parser.add_argument("--input", required=True)
- return parser.parse_args()
-
-
-def setup_logging():
- """
- Set up logging from the command line options
- """
- root_logger = logging.getLogger()
- formatter = logging.Formatter("%(asctime)s %(levelname)-5.5s %(message)s")
- stdout_handler = logging.StreamHandler(sys.stdout)
- stdout_handler.setFormatter(formatter)
- stdout_handler.setLevel(logging.DEBUG)
- root_logger.addHandler(stdout_handler)
- root_logger.setLevel(logging.DEBUG)
-
-
-class ScriptRC(object):
- """Enum for script return codes"""
- SUCCESS = 0
- FAILURE = 1
- EXCEPTION = 2
-
-
-class ScriptException(Exception):
- pass
-
-
-def main():
- # Get the options from the user.
- options = get_options()
-
- setup_logging()
-
- # Run main script.
- try:
- rc = read_corpus(options)
- except Exception as e:
- log.exception(e)
- rc = ScriptRC.EXCEPTION
-
- log.info("Returning %d", rc)
- return rc
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/tests/fuzz/standalone_fuzz_target_runner.cc b/tests/fuzz/standalone_fuzz_target_runner.cc
deleted file mode 100644
index 9b2316ed6..000000000
--- a/tests/fuzz/standalone_fuzz_target_runner.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2017, Max Dymond, <cmeister2@gmail.com>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "testinput.h"
-
-/**
- * Main procedure for standalone fuzzing engine.
- *
- * Reads filenames from the argument array. For each filename, read the file
- * into memory and then call the fuzzing interface with the data.
- */
-int main(int argc, char **argv)
-{
- int ii;
- FILE *infile;
- uint8_t *buffer = NULL;
- size_t buffer_len;
-
- for(ii = 1; ii < argc; ii++) {
- /* Try and open the file. */
- infile = fopen(argv[ii], "rb");
- if(infile) {
- printf("[%s] Open succeeded! \n", argv[ii]);
-
- /* Get the length of the file. */
- fseek(infile, 0L, SEEK_END);
- buffer_len = ftell(infile);
-
- /* Reset the file indicator to the beginning of the file. */
- fseek(infile, 0L, SEEK_SET);
-
- /* Allocate a buffer for the file contents. */
- buffer = (uint8_t *)calloc(buffer_len, sizeof(uint8_t));
- if(buffer) {
- /* Read all the text from the file into the buffer. */
- fread(buffer, sizeof(uint8_t), buffer_len, infile);
- printf("[%s] Read %zu bytes, calling fuzzer\n", argv[ii], buffer_len);
-
- /* Call the fuzzer with the data. */
- LLVMFuzzerTestOneInput(buffer, buffer_len);
-
- printf("[%s] Fuzzing complete\n", argv[ii]);
-
- /* Free the buffer as it's no longer needed. */
- free(buffer);
- buffer = NULL;
- }
- else
- {
- fprintf(stderr,
- "[%s] Failed to allocate %zu bytes \n",
- argv[ii],
- buffer_len);
- }
-
- /* Close the file as it's no longer needed. */
- fclose(infile);
- infile = NULL;
- }
- else
- {
- /* Failed to open the file. Maybe wrong name or wrong permissions? */
- fprintf(stderr, "[%s] Open failed. \n", argv[ii]);
- }
- }
-}
diff --git a/tests/fuzz/testinput.h b/tests/fuzz/testinput.h
deleted file mode 100644
index 0746cba73..000000000
--- a/tests/fuzz/testinput.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2017, Max Dymond, <cmeister2@gmail.com>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); \ No newline at end of file
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index 065899276..230416763 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -20,14 +20,14 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
lib559 lib560 lib562 lib564 lib565 lib566 lib567 lib568 lib569 lib570 \
lib571 lib572 lib573 lib574 lib575 lib576 lib578 lib579 lib582 \
lib583 lib585 lib586 lib587 lib589 lib590 lib591 lib597 lib598 lib599 \
- lib643 lib644 lib645 lib650 \
+ lib643 lib644 lib645 lib650 lib651 lib652 lib653 \
lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1507 lib1508 \
lib1509 lib1510 lib1511 lib1512 lib1513 lib1514 lib1515 lib1517 \
lib1520 lib1521 \
lib1525 lib1526 lib1527 lib1528 lib1529 lib1530 lib1531 lib1532 lib1533 \
lib1534 lib1535 lib1536 lib1537 lib1538 \
lib1540 \
- lib1550 lib1551 \
+ lib1550 lib1551 lib1552 lib1553 \
lib1900 \
lib2033
@@ -315,6 +315,15 @@ lib645_CPPFLAGS = $(AM_CPPFLAGS) -DLIB645
lib650_SOURCES = lib650.c $(SUPPORTFILES)
lib650_CPPFLAGS = $(AM_CPPFLAGS)
+lib651_SOURCES = lib651.c $(SUPPORTFILES)
+lib651_CPPFLAGS = $(AM_CPPFLAGS)
+
+lib652_SOURCES = lib652.c $(SUPPORTFILES)
+lib652_CPPFLAGS = $(AM_CPPFLAGS)
+
+lib653_SOURCES = lib653.c $(SUPPORTFILES)
+lib653_CPPFLAGS = $(AM_CPPFLAGS)
+
lib1500_SOURCES = lib1500.c $(SUPPORTFILES) $(TESTUTIL)
lib1500_LDADD = $(TESTUTIL_LIBS)
lib1500_CPPFLAGS = $(AM_CPPFLAGS)
@@ -454,6 +463,12 @@ lib1550_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1517
lib1551_SOURCES = lib1551.c $(SUPPORTFILES)
lib1551_CPPFLAGS = $(AM_CPPFLAGS)
+lib1552_SOURCES = lib1552.c $(SUPPORTFILES) $(TESTUTIL)
+lib1552_CPPFLAGS = $(AM_CPPFLAGS)
+
+lib1553_SOURCES = lib1553.c $(SUPPORTFILES) $(TESTUTIL)
+lib1553_CPPFLAGS = $(AM_CPPFLAGS)
+
lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1900_LDADD = $(TESTUTIL_LIBS)
lib1900_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/tests/libtest/lib1552.c b/tests/libtest/lib1552.c
new file mode 100644
index 000000000..02c4ea860
--- /dev/null
+++ b/tests/libtest/lib1552.c
@@ -0,0 +1,93 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+int test(char *URL)
+{
+ CURL *curls = NULL;
+ CURLM *multi = NULL;
+ int still_running;
+ int i = 0;
+ int res = 0;
+ CURLMsg *msg;
+ int counter = 3;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ multi_init(multi);
+
+ easy_init(curls);
+
+ easy_setopt(curls, CURLOPT_URL, URL);
+ easy_setopt(curls, CURLOPT_HEADER, 1L);
+ easy_setopt(curls, CURLOPT_VERBOSE, 1L);
+ easy_setopt(curls, CURLOPT_USERPWD, "u:s");
+
+ multi_add_handle(multi, curls);
+
+ multi_perform(multi, &still_running);
+
+ abort_on_test_timeout();
+
+ while(still_running && counter--) {
+ int num;
+ res = curl_multi_wait(multi, NULL, 0, TEST_HANG_TIMEOUT, &num);
+ if(res != CURLM_OK) {
+ printf("curl_multi_wait() returned %d\n", res);
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+
+ abort_on_test_timeout();
+
+ multi_perform(multi, &still_running);
+
+ abort_on_test_timeout();
+ }
+
+ msg = curl_multi_info_read(multi, &still_running);
+ if(msg)
+ /* this should now contain a result code from the easy handle,
+ get it */
+ i = msg->data.result;
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UA */
+
+ curl_multi_cleanup(multi);
+ curl_easy_cleanup(curls);
+ curl_global_cleanup();
+
+ if(res)
+ i = res;
+
+ return i; /* return the final return code */
+}
diff --git a/tests/libtest/lib1553.c b/tests/libtest/lib1553.c
new file mode 100644
index 000000000..60be7c1a7
--- /dev/null
+++ b/tests/libtest/lib1553.c
@@ -0,0 +1,109 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 60 * 1000
+
+static int xferinfo(void *p,
+ curl_off_t dltotal, curl_off_t dlnow,
+ curl_off_t ultotal, curl_off_t ulnow)
+{
+ (void)p;
+ (void)dlnow;
+ (void)dltotal;
+ (void)ulnow;
+ (void)ultotal;
+ fprintf(stderr, "xferinfo fail!\n");
+ return 1; /* fail as fast as we can */
+}
+
+int test(char *URL)
+{
+ CURL *curls = NULL;
+ CURLM *multi = NULL;
+ int still_running;
+ int i = 0;
+ int res = 0;
+ curl_mimepart *field = NULL;
+ curl_mime *mime = NULL;
+ int counter = 1;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ multi_init(multi);
+
+ easy_init(curls);
+
+ mime = curl_mime_init(curls);
+ field = curl_mime_addpart(mime);
+ curl_mime_name(field, "name");
+ curl_mime_data(field, "value", CURL_ZERO_TERMINATED);
+
+ easy_setopt(curls, CURLOPT_URL, URL);
+ easy_setopt(curls, CURLOPT_HEADER, 1L);
+ easy_setopt(curls, CURLOPT_VERBOSE, 1L);
+ easy_setopt(curls, CURLOPT_MIMEPOST, mime);
+ easy_setopt(curls, CURLOPT_USERPWD, "u:s");
+ easy_setopt(curls, CURLOPT_XFERINFOFUNCTION, xferinfo);
+ easy_setopt(curls, CURLOPT_NOPROGRESS, 1L);
+
+ multi_add_handle(multi, curls);
+
+ multi_perform(multi, &still_running);
+
+ abort_on_test_timeout();
+
+ while(still_running && counter--) {
+ int num;
+ res = curl_multi_wait(multi, NULL, 0, TEST_HANG_TIMEOUT, &num);
+ if(res != CURLM_OK) {
+ printf("curl_multi_wait() returned %d\n", res);
+ res = TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+
+ abort_on_test_timeout();
+
+ multi_perform(multi, &still_running);
+
+ abort_on_test_timeout();
+ }
+
+test_cleanup:
+
+ curl_mime_free(mime);
+ curl_multi_remove_handle(multi, curls);
+ curl_multi_cleanup(multi);
+ curl_easy_cleanup(curls);
+ curl_global_cleanup();
+
+ if(res)
+ i = res;
+
+ return i; /* return the final return code */
+}
diff --git a/tests/libtest/lib554.c b/tests/libtest/lib554.c
index 936d0a10a..cc21d245b 100644
--- a/tests/libtest/lib554.c
+++ b/tests/libtest/lib554.c
@@ -117,7 +117,7 @@ static int once(char *URL, bool oldstyle)
CURLFORM_END);
if(formrc)
- printf("curl_formadd(1) = %d\n", (int)formrc);
+ printf("curl_formadd(2) = %d\n", (int)formrc);
/* Fill in the filename field */
formrc = curl_formadd(&formpost,
@@ -134,7 +134,7 @@ static int once(char *URL, bool oldstyle)
CURLFORM_END);
if(formrc)
- printf("curl_formadd(2) = %d\n", (int)formrc);
+ printf("curl_formadd(3) = %d\n", (int)formrc);
/* Fill in a submit field too */
formrc = curl_formadd(&formpost,
@@ -147,10 +147,11 @@ static int once(char *URL, bool oldstyle)
#else
CURLFORM_COPYCONTENTS, "send",
#endif
+ CURLFORM_CONTENTTYPE, "text/plain",
CURLFORM_END);
if(formrc)
- printf("curl_formadd(3) = %d\n", (int)formrc);
+ printf("curl_formadd(4) = %d\n", (int)formrc);
formrc = curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "somename",
@@ -160,7 +161,7 @@ static int once(char *URL, bool oldstyle)
CURLFORM_END);
if(formrc)
- printf("curl_formadd(4) = %d\n", (int)formrc);
+ printf("curl_formadd(5) = %d\n", (int)formrc);
curl = curl_easy_init();
if(!curl) {
diff --git a/tests/libtest/lib643.c b/tests/libtest/lib643.c
index e26a2515f..7432dfce8 100644
--- a/tests/libtest/lib643.c
+++ b/tests/libtest/lib643.c
@@ -251,6 +251,30 @@ test_cleanup:
return res;
}
+static int cyclic_add(void)
+{
+ CURL *easy = curl_easy_init();
+ curl_mime *mime = curl_mime_init(easy);
+ curl_mimepart *part = curl_mime_addpart(mime);
+ CURLcode a1 = curl_mime_subparts(part, mime);
+
+ if(a1 == CURLE_BAD_FUNCTION_ARGUMENT) {
+ curl_mime *submime = curl_mime_init(easy);
+ curl_mimepart *subpart = curl_mime_addpart(submime);
+
+ curl_mime_subparts(part, submime);
+ a1 = curl_mime_subparts(subpart, mime);
+ }
+
+ curl_mime_free(mime);
+ curl_easy_cleanup(easy);
+ if(a1 != CURLE_BAD_FUNCTION_ARGUMENT)
+ /* that should have failed */
+ return 1;
+
+ return 0;
+}
+
int test(char *URL)
{
int res;
@@ -264,6 +288,9 @@ int test(char *URL)
if(!res)
res = once(URL, FALSE); /* new */
+ if(!res)
+ res = cyclic_add();
+
curl_global_cleanup();
return res;
diff --git a/tests/libtest/lib650.c b/tests/libtest/lib650.c
index 130ef1e77..60a2e9f1d 100644
--- a/tests/libtest/lib650.c
+++ b/tests/libtest/lib650.c
@@ -68,10 +68,14 @@ int test(char *URL)
return TEST_ERR_MAJOR_BAD;
}
- /* Check proper name and data copying. */
+ /* Check proper name and data copying, as well as headers. */
+ headers = curl_slist_append(headers, "X-customheader-1: Header 1 data");
+ headers = curl_slist_append(headers, "X-customheader-2: Header 2 data");
+ headers = curl_slist_append(headers, "Content-Type: text/plain");
formrc = curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, &name,
CURLFORM_COPYCONTENTS, &data,
+ CURLFORM_CONTENTHEADER, headers,
CURLFORM_END);
if(formrc)
@@ -113,18 +117,15 @@ int test(char *URL)
if(formrc)
printf("curl_formadd(3) = %d\n", (int) formrc);
- /* Check data from file content and headers. */
- headers = curl_slist_append(headers, "X-customheader-1: Header 1 data");
- headers = curl_slist_append(headers, "X-customheader-2: Header 2 data");
+ /* Check data from file content. */
formrc = curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "filecontents",
CURLFORM_FILECONTENT, libtest_arg2,
- CURLFORM_CONTENTHEADER, headers,
CURLFORM_END);
if(formrc)
- printf("curl_formadd(3) = %d\n", (int) formrc);
+ printf("curl_formadd(4) = %d\n", (int) formrc);
/* Measure the current form length.
* This is done before including stdin data because we want to reuse it
@@ -148,7 +149,7 @@ int test(char *URL)
CURLFORM_END);
if(formrc)
- printf("curl_formadd(4) = %d\n", (int) formrc);
+ printf("curl_formadd(5) = %d\n", (int) formrc);
curl = curl_easy_init();
if(!curl) {
diff --git a/tests/libtest/lib651.c b/tests/libtest/lib651.c
new file mode 100644
index 000000000..18bcaae83
--- /dev/null
+++ b/tests/libtest/lib651.c
@@ -0,0 +1,94 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static char buffer[17000]; /* more than 16K */
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+ CURLFORMcode formrc;
+ struct curl_httppost *formpost = NULL;
+ struct curl_httppost *lastptr = NULL;
+
+ /* create a buffer with AAAA...BBBBB...CCCC...etc */
+ int i;
+ int size = (int)sizeof(buffer)/1000;
+
+ for(i = 0; i < size ; i++)
+ memset(&buffer[i * 1000], 65 + i, 1000);
+
+ buffer[ sizeof(buffer)-1] = 0; /* zero terminate */
+
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* Check proper name and data copying. */
+ formrc = curl_formadd(&formpost, &lastptr,
+ CURLFORM_COPYNAME, "hello",
+ CURLFORM_COPYCONTENTS, buffer,
+ CURLFORM_END);
+
+ if(formrc)
+ printf("curl_formadd(1) = %d\n", (int) formrc);
+
+
+ curl = curl_easy_init();
+ if(!curl) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_formfree(formpost);
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ /* First set the URL that is about to receive our POST. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* send a multi-part formpost */
+ test_setopt(curl, CURLOPT_HTTPPOST, formpost);
+
+ /* get verbose debug output please */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* include headers in the output */
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ /* now cleanup the formpost chain */
+ curl_formfree(formpost);
+
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib652.c b/tests/libtest/lib652.c
new file mode 100644
index 000000000..d60390b2f
--- /dev/null
+++ b/tests/libtest/lib652.c
@@ -0,0 +1,128 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "memdebug.h"
+
+static char buffer[17000]; /* more than 16K */
+
+int test(char *URL)
+{
+ CURL *curl = NULL;
+ CURLcode res = CURLE_OK;
+ curl_mime *mime = NULL;
+ curl_mimepart *part;
+ struct curl_slist *recipients = NULL;
+
+ /* create a buffer with AAAA...BBBBB...CCCC...etc */
+ int i;
+ int size = (int)sizeof(buffer) / 10;
+
+ for(i = 0; i < size ; i++)
+ memset(&buffer[i * 10], 65 + (i % 26), 10);
+
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ curl = curl_easy_init();
+ if(!curl) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ res = (CURLcode) TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+
+ /* Build mime structure. */
+ mime = curl_mime_init(curl);
+ if(!mime) {
+ fprintf(stderr, "curl_mime_init() failed\n");
+ res = (CURLcode) TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ part = curl_mime_addpart(mime);
+ if(!part) {
+ fprintf(stderr, "curl_mime_addpart() failed\n");
+ res = (CURLcode) TEST_ERR_MAJOR_BAD;
+ goto test_cleanup;
+ }
+ res = curl_mime_filename(part, "myfile.jpg");
+ if(res) {
+ fprintf(stderr, "curl_mime_filename() failed\n");
+ goto test_cleanup;
+ }
+ res = curl_mime_type(part, "image/jpeg");
+ if(res) {
+ fprintf(stderr, "curl_mime_type() failed\n");
+ goto test_cleanup;
+ }
+ res = curl_mime_data(part, buffer, sizeof buffer);
+ if(res) {
+ fprintf(stderr, "curl_mime_data() failed\n");
+ goto test_cleanup;
+ }
+ res = curl_mime_encoder(part, "base64");
+ if(res) {
+ fprintf(stderr, "curl_mime_encoder() failed\n");
+ goto test_cleanup;
+ }
+
+ /* Prepare recipients. */
+ recipients = curl_slist_append(NULL, "someone@example.com");
+ if(!recipients) {
+ fprintf(stderr, "curl_slist_append() failed\n");
+ goto test_cleanup;
+ }
+
+ /* First set the URL that is about to receive our mime mail. */
+ test_setopt(curl, CURLOPT_URL, URL);
+
+ /* Set sender. */
+ test_setopt(curl, CURLOPT_MAIL_FROM, "somebody@example.com");
+
+ /* Set recipients. */
+ test_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
+
+ /* send a multi-part mail */
+ test_setopt(curl, CURLOPT_MIMEPOST, mime);
+
+ /* get verbose debug output please */
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ /* now cleanup the mime structure */
+ curl_mime_free(mime);
+
+ /* cleanup the recipients. */
+ curl_slist_free_all(recipients);
+
+ curl_global_cleanup();
+
+ return res;
+}
diff --git a/tests/libtest/lib653.c b/tests/libtest/lib653.c
new file mode 100644
index 000000000..6d78ee0f4
--- /dev/null
+++ b/tests/libtest/lib653.c
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+
+int test(char *URL)
+{
+ CURL *curls = NULL;
+ int res = 0;
+ curl_mimepart *field = NULL;
+ curl_mime *mime = NULL;
+
+ global_init(CURL_GLOBAL_ALL);
+ easy_init(curls);
+
+ mime = curl_mime_init(curls);
+ field = curl_mime_addpart(mime);
+ curl_mime_name(field, "name");
+ curl_mime_data(field, "short value", CURL_ZERO_TERMINATED);
+
+ easy_setopt(curls, CURLOPT_URL, URL);
+ easy_setopt(curls, CURLOPT_HEADER, 1L);
+ easy_setopt(curls, CURLOPT_VERBOSE, 1L);
+ easy_setopt(curls, CURLOPT_MIMEPOST, mime);
+ easy_setopt(curls, CURLOPT_NOPROGRESS, 1L);
+
+ res = curl_easy_perform(curls);
+ if(res)
+ goto test_cleanup;
+
+ /* Alter form and resubmit. */
+ curl_mime_data(field, "long value for length change", CURL_ZERO_TERMINATED);
+ res = curl_easy_perform(curls);
+
+test_cleanup:
+ curl_mime_free(mime);
+ curl_easy_cleanup(curls);
+ curl_global_cleanup();
+ return (int) res; /* return the final return code */
+}
diff --git a/tests/memanalyze.pl b/tests/memanalyze.pl
index 35d1c7ef7..8ba3f6dd5 100755
--- a/tests/memanalyze.pl
+++ b/tests/memanalyze.pl
@@ -6,7 +6,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -33,6 +33,9 @@ my $reallocs=0;
my $strdups=0;
my $wcsdups=0;
my $showlimit;
+my $sends=0;
+my $recvs=0;
+my $sockets=0;
while(1) {
if($ARGV[0] eq "-v") {
@@ -258,6 +261,7 @@ while(<FILE>) {
$filedes{$1}=1;
$getfile{$1}="$source:$linenum";
$openfile++;
+ $sockets++; # number of socket() calls
}
elsif($function =~ /socketpair\(\) = (\d*) (\d*)/) {
$filedes{$1}=1;
@@ -314,6 +318,14 @@ while(<FILE>) {
elsif($_ =~ /^GETNAME ([^ ]*):(\d*) (.*)/) {
# not much to do
}
+ # SEND url.c:1901 send(83) = 83
+ elsif($_ =~ /^SEND ([^ ]*):(\d*) (.*)/) {
+ $sends++;
+ }
+ # RECV url.c:1901 recv(102400) = 256
+ elsif($_ =~ /^RECV ([^ ]*):(\d*) (.*)/) {
+ $recvs++;
+ }
# ADDR url.c:1282 getaddrinfo() = 0x5ddd
elsif($_ =~ /^ADDR ([^ ]*):(\d*) (.*)/) {
@@ -398,12 +410,16 @@ if($addrinfos) {
if($verbose) {
print "Mallocs: $mallocs\n",
- "Reallocs: $reallocs\n",
- "Callocs: $callocs\n",
- "Strdups: $strdups\n",
- "Wcsdups: $wcsdups\n",
- "Frees: $frees\n",
- "Allocations: ".($mallocs + $callocs + $reallocs + $strdups + $wcsdups)."\n";
+ "Reallocs: $reallocs\n",
+ "Callocs: $callocs\n",
+ "Strdups: $strdups\n",
+ "Wcsdups: $wcsdups\n",
+ "Frees: $frees\n",
+ "Sends: $sends\n",
+ "Recvs: $recvs\n",
+ "Sockets: $sockets\n",
+ "Allocations: ".($mallocs + $callocs + $reallocs + $strdups + $wcsdups)."\n",
+ "Operations: ".($mallocs + $callocs + $reallocs + $strdups + $wcsdups + $sends + $recvs + $sockets)."\n";
print "Maximum allocated: $maxmem\n";
}
diff --git a/tests/runtests.pl b/tests/runtests.pl
index 66919bcd7..a886a28f9 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -233,6 +233,7 @@ my $has_cares; # set if built with c-ares
my $has_threadedres;# set if built with threaded resolver
my $has_psl; # set if libcurl is built with PSL support
my $has_ldpreload; # set if curl is built for systems supporting LD_PRELOAD
+my $has_multissl; # set if curl is build with MultiSSL support
# this version is decided by the particular nghttp2 library that is being used
my $h2cver = "h2c";
@@ -561,8 +562,7 @@ sub runclientoutput {
# Memory allocation test and failure torture testing.
#
sub torture {
- my $testcmd = shift;
- my $gdbline = shift;
+ my ($testcmd, $testnum, $gdbline) = @_;
# remove memdump first to be sure we get a new nice and clean one
unlink($memdump);
@@ -576,17 +576,17 @@ sub torture {
my $count=0;
my @out = `$memanalyze -v $memdump`;
for(@out) {
- if(/^Allocations: (\d+)/) {
+ if(/^Operations: (\d+)/) {
$count = $1;
last;
}
}
if(!$count) {
- logmsg " found no allocs to make fail\n";
+ logmsg " found no functions to make fail\n";
return 0;
}
- logmsg " $count allocations to make fail\n";
+ logmsg " $count functions to make fail\n";
for ( 1 .. $count ) {
my $limit = $_;
@@ -601,7 +601,7 @@ sub torture {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime(time());
my $now = sprintf("%02d:%02d:%02d ", $hour, $min, $sec);
- logmsg "Fail alloc no: $limit at $now\r";
+ logmsg "Fail funcion no: $limit at $now\r";
}
# make the memory allocation function number $limit return failure
@@ -610,14 +610,28 @@ sub torture {
# remove memdump first to be sure we get a new nice and clean one
unlink($memdump);
- logmsg "*** Alloc number $limit is now set to fail ***\n" if($gdbthis);
+ my $cmd = $testcmd;
+ if($valgrind && !$gdbthis) {
+ my @valgrindoption = getpart("verify", "valgrind");
+ if((!@valgrindoption) || ($valgrindoption[0] !~ /disable/)) {
+ my $valgrindcmd = "$valgrind ";
+ $valgrindcmd .= "$valgrind_tool " if($valgrind_tool);
+ $valgrindcmd .= "--quiet --leak-check=yes ";
+ $valgrindcmd .= "--suppressions=$srcdir/valgrind.supp ";
+ # $valgrindcmd .= "--gen-suppressions=all ";
+ $valgrindcmd .= "--num-callers=16 ";
+ $valgrindcmd .= "${valgrind_logfile}=$LOGDIR/valgrind$testnum";
+ $cmd = "$valgrindcmd $testcmd";
+ }
+ }
+ logmsg "*** Function number $limit is now set to fail ***\n" if($gdbthis);
my $ret = 0;
if($gdbthis) {
runclient($gdbline);
}
else {
- $ret = runclient($testcmd);
+ $ret = runclient($cmd);
}
#logmsg "$_ Returned " . ($ret >> 8) . "\n";
@@ -631,6 +645,20 @@ sub torture {
$fail = 2;
}
+ if($valgrind) {
+ my @e = valgrindparse("$LOGDIR/valgrind$testnum");
+ if(@e && $e[0]) {
+ if($automakestyle) {
+ logmsg "FAIL: torture $testnum - valgrind\n";
+ }
+ else {
+ logmsg " valgrind ERROR ";
+ logmsg @e;
+ }
+ $fail = 1;
+ }
+ }
+
# verify that it returns a proper error code, doesn't leak memory
# and doesn't core dump
if(($ret & 255) || ($ret >> 8) >= 128) {
@@ -655,7 +683,7 @@ sub torture {
}
}
if($fail) {
- logmsg " Failed on alloc number $limit in test.\n",
+ logmsg " Failed on function number $limit in test.\n",
" invoke with \"-t$limit\" to repeat this single case.\n";
stopservers($verbose);
return 1;
@@ -2831,6 +2859,10 @@ sub checksystem {
# ssl enabled
$has_ssl=1;
}
+ if($feat =~ /MultiSSL/i) {
+ # multiple ssl backends available.
+ $has_multissl=1;
+ }
if($feat =~ /Largefile/i) {
# large file support
$has_largefile=1;
@@ -3173,7 +3205,7 @@ sub fixarray {
my @in = @_;
for(@in) {
- subVariables \$_;
+ subVariables(\$_);
}
return @in;
}
@@ -3284,6 +3316,11 @@ sub singletest {
next;
}
}
+ elsif($1 eq "MultiSSL") {
+ if($has_multissl) {
+ next;
+ }
+ }
elsif($1 eq "SSLpinning") {
if($has_sslpinning) {
next;
@@ -3452,6 +3489,11 @@ sub singletest {
next;
}
}
+ elsif($1 eq "MultiSSL") {
+ if(!$has_multissl) {
+ next;
+ }
+ }
elsif($1 eq "OpenSSL") {
if(!$has_openssl) {
next;
@@ -3638,7 +3680,7 @@ sub singletest {
if(@setenv) {
foreach my $s (@setenv) {
chomp $s;
- subVariables \$s;
+ subVariables(\$s);
if($s =~ /([^=]*)=(.*)/) {
my ($var, $content) = ($1, $2);
# remember current setting, to restore it once test runs
@@ -4003,7 +4045,8 @@ sub singletest {
# run the command line we built
if ($torture) {
$cmdres = torture($CMDLINE,
- "$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
+ $testnum,
+ "$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
}
elsif($gdbthis) {
my $GDBW = ($gdbxwin) ? "-w" : "";
@@ -5310,8 +5353,6 @@ while(@ARGV) {
if($xtra =~ s/(\d+)$//) {
$tortalloc = $1;
}
- # we undef valgrind to make this fly in comparison
- undef $valgrind;
}
elsif($ARGV[0] eq "-a") {
# continue anyway, even if a test fail
@@ -5377,7 +5418,7 @@ Usage: runtests.pl [options] [test selection(s)]
-rf full run time statistics
-s short output
-am automake style output PASS/FAIL: [number] [name]
- -t[N] torture (simulate memory alloc failures); N means fail Nth alloc
+ -t[N] torture (simulate function failures); N means fail Nth function
-v verbose output
-vc path use this curl only to verify the existing servers
[num] like "5 6 9" or " 5 to 22 " to run those tests only
diff --git a/winbuild/BUILD.WINDOWS.txt b/winbuild/BUILD.WINDOWS.txt
index 7b0d5ba86..1840991fe 100644
--- a/winbuild/BUILD.WINDOWS.txt
+++ b/winbuild/BUILD.WINDOWS.txt
@@ -71,6 +71,7 @@ where <options> is one or many of:
Libraries can be fetched at http://windows.php.net/downloads/php-sdk/deps/
Uncompress them into the deps folder.
WITH_SSL=<dll or static> - Enable OpenSSL support, DLL or static
+ WITH_NGHTTP2=<dll or static> - Enable HTTP/2 support, DLL or static
WITH_MBEDTLS=<dll or static> - Enable mbedTLS support, DLL or static
WITH_CARES=<dll or static> - Enable c-ares support, DLL or static
WITH_ZLIB=<dll or static> - Enable zlib support, DLL or static