From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from sa-prd-fep-049.btinternet.com (mailomta13-sa.btinternet.com [213.120.69.19]) by sourceware.org (Postfix) with ESMTPS id E2B6C3858407 for ; Sun, 13 Feb 2022 16:16:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E2B6C3858407 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=dronecode.org.uk Authentication-Results: sourceware.org; spf=none smtp.mailfrom=dronecode.org.uk Received: from sa-prd-rgout-002.btmx-prd.synchronoss.net ([10.2.38.5]) by sa-prd-fep-049.btinternet.com with ESMTP id <20220213161624.WDYD30507.sa-prd-fep-049.btinternet.com@sa-prd-rgout-002.btmx-prd.synchronoss.net>; Sun, 13 Feb 2022 16:16:24 +0000 Authentication-Results: btinternet.com; auth=pass (LOGIN) smtp.auth=jonturney@btinternet.com; bimi=skipped X-SNCR-Rigid: 6139417C154E8BA5 X-Originating-IP: [86.139.167.74] X-OWM-Source-IP: 86.139.167.74 (GB) X-OWM-Env-Sender: jonturney@btinternet.com X-VadeSecure-score: verdict=clean score=0/300, class=clean X-RazorGate-Vade: gggruggvucftvghtrhhoucdtuddrgedvvddrjedtgdekvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemuceutffkvffkuffjvffgnffgvefqofdpqfgfvfenuceurghilhhouhhtmecufedtudenucenucfjughrpefhvffufffkofgggfestdekredtredttdenucfhrhhomheplfhonhcuvfhurhhnvgihuceojhhonhdrthhurhhnvgihsegurhhonhgvtghouggvrdhorhhgrdhukheqnecuggftrfgrthhtvghrnhepueeijeeguddvuedtffeiieelfeffudefkeehgfejffefhedtkeejgeekfedtffefnecukfhppeekiedrudefledrudeijedrjeegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehhvghloheplhhotggrlhhhohhsthdrlhhotggrlhguohhmrghinhdpihhnvghtpeekiedrudefledrudeijedrjeegpdhmrghilhhfrhhomhepjhhonhdrthhurhhnvgihsegurhhonhgvtghouggvrdhorhhgrdhukhdpnhgspghrtghpthhtohepvddprhgtphhtthhopegthihgfihinhdqrghpphhssegthihgfihinhdrtghomhdprhgtphhtthhopehjohhnrdhtuhhrnhgvhiesughrohhnvggtohguvgdrohhrghdruhhk X-RazorGate-Vade-Verdict: clean 0 X-RazorGate-Vade-Classification: clean Received: from localhost.localdomain (86.139.167.74) by sa-prd-rgout-002.btmx-prd.synchronoss.net (5.8.716.04) (authenticated as jonturney@btinternet.com) id 6139417C154E8BA5; Sun, 13 Feb 2022 16:16:24 +0000 From: Jon Turney To: cygwin-apps@cygwin.com Cc: Jon Turney Subject: [PATCH setup] Handle tar type flag 'K' (GNU long link extension) Date: Sun, 13 Feb 2022 16:15:33 +0000 Message-Id: <20220213161534.59794-1-jon.turney@dronecode.org.uk> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1200.1 required=5.0 tests=BAYES_00, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: cygwin-apps@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin package maintainer discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Feb 2022 16:16:28 -0000 Handle tar type flag'K' (GNU long link extension) Also report unexpected filename in headers with long name extension type Also clean up some cruft in archive_tar.cc Currently, the only existing package which contains type flag 'K' entries is f21-backgrounds-extras. This also now correctly handles tar archive header linknames of exactly 100 characters (even when not preceeded by a 'K' type header), where the linkname field is not null terminated as it should be, rather than allowing the 'ustar\0' magic immediately following it to be interpreted as part of the linkname. --- archive_tar.cc | 62 ++++++++++++++++++++++++++++++++------------------ archive_tar.h | 2 ++ 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/archive_tar.cc b/archive_tar.cc index 5b2a771..63269a6 100644 --- a/archive_tar.cc +++ b/archive_tar.cc @@ -21,9 +21,7 @@ #include #include -//#include "zlib/zlib.h" #include "io_stream.h" -//#include "compress.h" #include "win32.h" #include "archive.h" #include "archive_tar.h" @@ -31,14 +29,7 @@ #include "LogFile.h" #include "filemanip.h" -#if 0 -#undef _WIN32 -#include "bzlib.h" - -#define SYMLINK_COOKIE "!" -#endif static int err; - static char buf[512]; int _tar_verbose = 0; @@ -154,13 +145,26 @@ archive_tar::next_file_name () if (n == 0) return std::string(); - if (!state.have_longname && state.tar_header.typeflag != 'L') + if (!state.have_longname) { memcpy (state.filename, state.tar_header.name, 100); state.filename[100] = 0; } - else if (state.have_longname) - state.have_longname = 0; + + if (!state.have_longlink) + { + memcpy (state.linkname, state.tar_header.linkname, 100); + state.linkname[100] = 0; + } + + /* typeflag for any 'real' file consumes the longname/longlink state from + previous blocks */ + if ((state.tar_header.typeflag != 'K') && + (state.tar_header.typeflag != 'L')) + { + state.have_longname = 0; + state.have_longlink = 0; + } sscanf (state.tar_header.size, "%zo", &state.file_length); state.file_offset = 0; @@ -171,9 +175,13 @@ archive_tar::next_file_name () switch (state.tar_header.typeflag) { + case 'K': /* GNU tar long link extension */ case 'L': /* GNU tar long name extension */ - /* we read the 'file' into the long filename, then call back into here - * to find out if the actual file is a real file, or a special file.. + if (strcmp(state.tar_header.name, "././@LongLink") != 0) + LogBabblePrintf("tar: unexpected filename %s in file type %c header\n", state.tar_header.name, state.tar_header.typeflag); + + /* we read the 'file' into the long filename/linkname, then recursively + * call ourselves to handle the following block. */ if (state.file_length > CYG_PATH_MAX) { @@ -187,7 +195,18 @@ archive_tar::next_file_name () skip_file (); return next_file_name (); } - c = state.filename; + + if (state.tar_header.typeflag == 'L') + { + c = state.filename; + state.have_longname = 1; + } + else + { + c = state.linkname; + state.have_longlink = 1; + } + /* FIXME: this should be a single read() call */ while (state.file_length > state.file_offset) { @@ -195,17 +214,16 @@ archive_tar::next_file_name () state.file_length - state.file_offset > 512 ? 512 : state.file_length - state.file_offset; if (state.parent->read (buf, 512) < 512) - // FIXME: What's up with the "0"? It's probably a mistake, and - // should be "". It used to be written as 0, and was subject to a - // bizarre implicit conversion by the unwise String(int) - // constructor. - return "0"; + { + LogPlainPrintf( "error: error reading long name\n"); + return ""; + } memcpy (c, buf, need); c += need; state.file_offset += need; } *c = 0; - state.have_longname = 1; + return next_file_name (); case '3': /* char */ @@ -297,7 +315,7 @@ archive_tar::linktarget () /* TODO: consider .. path traversal issues */ if (next_file_type () == ARCHIVE_FILE_SYMLINK || next_file_type () == ARCHIVE_FILE_HARDLINK) - return state.tar_header.linkname; + return state.linkname; return std::string(); } diff --git a/archive_tar.h b/archive_tar.h index cc0a46c..3adc056 100644 --- a/archive_tar.h +++ b/archive_tar.h @@ -66,12 +66,14 @@ public: int lasterr; int eocf; char have_longname; + bool have_longlink; /* where in the current file are we? */ size_t file_offset; size_t file_length; int header_read; tar_header_type tar_header; char filename[CYG_PATH_MAX + 512]; + char linkname[CYG_PATH_MAX + 512]; tar_map_result_type *tar_map_result; }; -- 2.35.1