From owner-svn-src-all@freebsd.org Fri Mar 13 01:05:42 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id C8D9527053E; Fri, 13 Mar 2020 01:05:42 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48dnYy5jK2z4ZWC; Fri, 13 Mar 2020 01:05:42 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id BB0832DFD2; Fri, 13 Mar 2020 01:05:42 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 02D15gdo033418; Fri, 13 Mar 2020 01:05:42 GMT (envelope-from mm@FreeBSD.org) Received: (from mm@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 02D15eu0033405; Fri, 13 Mar 2020 01:05:40 GMT (envelope-from mm@FreeBSD.org) Message-Id: <202003130105.02D15eu0033405@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mm set sender to mm@FreeBSD.org using -f From: Martin Matuska Date: Fri, 13 Mar 2020 01:05:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r358925 - in stable/12/contrib/libarchive: cpio cpio/test libarchive libarchive/test X-SVN-Group: stable-12 X-SVN-Commit-Author: mm X-SVN-Commit-Paths: in stable/12/contrib/libarchive: cpio cpio/test libarchive libarchive/test X-SVN-Commit-Revision: 358925 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Mar 2020 01:05:42 -0000 Author: mm Date: Fri Mar 13 01:05:40 2020 New Revision: 358925 URL: https://svnweb.freebsd.org/changeset/base/358925 Log: MFC r358533: Sync libarchive with vendor. Relevant vendor changes: Issue #1257: Add testcase for ZIPX files with LZMA_STREAM_END marker PR #1331: cpio.5: fix hard link description Issue #1335: archive_read.c: fix UBSan warning about undefined behavior Issue #1338: XAR reader: fix UBSan warning about undefined behavior Issue #1339: bsdcpio_test: fix datatype in from_hex() Issue #1341: Safe writes: delete temporary file if rename fails. Issue #1341: Safe writes: improve error handling Added: stable/12/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu - copied unchanged from r358533, head/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu Modified: stable/12/contrib/libarchive/cpio/cpio.c stable/12/contrib/libarchive/cpio/cpio.h stable/12/contrib/libarchive/cpio/test/test_format_newc.c stable/12/contrib/libarchive/libarchive/archive_read.c stable/12/contrib/libarchive/libarchive/archive_read_open_filename.c stable/12/contrib/libarchive/libarchive/archive_read_support_format_xar.c stable/12/contrib/libarchive/libarchive/archive_util.c stable/12/contrib/libarchive/libarchive/archive_write_disk_posix.c stable/12/contrib/libarchive/libarchive/archive_write_set_format_xar.c stable/12/contrib/libarchive/libarchive/cpio.5 stable/12/contrib/libarchive/libarchive/test/test_read_format_zip.c Modified: stable/12/contrib/libarchive/cpio/cpio.c ============================================================================== --- stable/12/contrib/libarchive/cpio/cpio.c Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/cpio/cpio.c Fri Mar 13 01:05:40 2020 (r358925) @@ -737,7 +737,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath */ destpath = srcpath; if (cpio->destdir) { - len = strlen(cpio->destdir) + strlen(srcpath) + 8; + len = cpio->destdir_len + strlen(srcpath) + 8; if (len >= cpio->pass_destpath_alloc) { while (len >= cpio->pass_destpath_alloc) { cpio->pass_destpath_alloc += 512; @@ -1228,15 +1228,14 @@ mode_pass(struct cpio *cpio, const char *destdir) struct lafe_line_reader *lr; const char *p; int r; - size_t destdir_len; /* Ensure target dir has a trailing '/' to simplify path surgery. */ - destdir_len = strlen(destdir); - cpio->destdir = malloc(destdir_len + 8); - memcpy(cpio->destdir, destdir, destdir_len); - if (destdir_len == 0 || destdir[destdir_len - 1] != '/') - cpio->destdir[destdir_len++] = '/'; - cpio->destdir[destdir_len++] = '\0'; + cpio->destdir_len = strlen(destdir); + cpio->destdir = malloc(cpio->destdir_len + 8); + memcpy(cpio->destdir, destdir, cpio->destdir_len); + if (cpio->destdir_len == 0 || destdir[cpio->destdir_len - 1] != '/') + cpio->destdir[cpio->destdir_len++] = '/'; + cpio->destdir[cpio->destdir_len] = '\0'; cpio->archive = archive_write_disk_new(); if (cpio->archive == NULL) Modified: stable/12/contrib/libarchive/cpio/cpio.h ============================================================================== --- stable/12/contrib/libarchive/cpio/cpio.h Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/cpio/cpio.h Fri Mar 13 01:05:40 2020 (r358925) @@ -64,6 +64,7 @@ struct cpio { int option_numeric_uid_gid; /* -n */ int option_rename; /* -r */ char *destdir; + size_t destdir_len; size_t pass_destpath_alloc; char *pass_destpath; int uid_override; Modified: stable/12/contrib/libarchive/cpio/test/test_format_newc.c ============================================================================== --- stable/12/contrib/libarchive/cpio/test/test_format_newc.c Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/cpio/test/test_format_newc.c Fri Mar 13 01:05:40 2020 (r358925) @@ -49,10 +49,11 @@ is_hex(const char *p, size_t l) return (1); } -static int +/* Convert up to 8 hex characters to unsigned 32-bit decimal integer */ +static uint32_t from_hex(const char *p, size_t l) { - int r = 0; + uint32_t r = 0; while (l > 0) { r *= 16; @@ -82,11 +83,11 @@ DEFINE_TEST(test_format_newc) { FILE *list; int r; - int devmajor, devminor, ino, gid; - int uid = -1; + uint32_t devmajor, devminor, ino, gid, uid; time_t t, t2, now; char *p, *e; - size_t s, fs, ns; + size_t s; + uint64_t fs, ns; char result[1024]; assertUmask(0); @@ -199,9 +200,11 @@ DEFINE_TEST(test_format_newc) #else assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */ #endif - if (uid < 0) - uid = from_hex(e + 22, 8); +#if defined(_WIN32) + uid = from_hex(e + 22, 8); +#else assertEqualInt(from_hex(e + 22, 8), uid); /* uid */ +#endif gid = from_hex(e + 30, 8); /* gid */ assertEqualMem(e + 38, "00000003", 8); /* nlink */ t = from_hex(e + 46, 8); /* mtime */ @@ -215,14 +218,14 @@ DEFINE_TEST(test_format_newc) " first appearance should be empty, so this file size\n" " field should be zero"); assertEqualInt(0, from_hex(e + 54, 8)); /* File size */ - fs = from_hex(e + 54, 8); + fs = (uint64_t)from_hex(e + 54, 8); fs += PAD(fs, 4); devmajor = from_hex(e + 62, 8); /* devmajor */ devminor = from_hex(e + 70, 8); /* devminor */ assert(is_hex(e + 78, 8)); /* rdevmajor */ assert(is_hex(e + 86, 8)); /* rdevminor */ assertEqualMem(e + 94, "00000006", 8); /* Name size */ - ns = from_hex(e + 94, 8); + ns = (uint64_t)from_hex(e + 94, 8); ns += PAD(ns + 2, 4); assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ assertEqualMem(e + 110, "file1\0", 6); /* Name contents */ @@ -249,14 +252,14 @@ DEFINE_TEST(test_format_newc) " at t2=%#08jx", (intmax_t)t, (intmax_t)t2); assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ assertEqualMem(e + 54, "00000005", 8); /* File size */ - fs = from_hex(e + 54, 8); + fs = (uint64_t)from_hex(e + 54, 8); fs += PAD(fs, 4); assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */ assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */ assert(is_hex(e + 78, 8)); /* rdevmajor */ assert(is_hex(e + 86, 8)); /* rdevminor */ assertEqualMem(e + 94, "00000008", 8); /* Name size */ - ns = from_hex(e + 94, 8); + ns = (uint64_t)from_hex(e + 94, 8); ns += PAD(ns + 2, 4); assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */ @@ -285,14 +288,14 @@ DEFINE_TEST(test_format_newc) "t2=%#08jx", (intmax_t)t, (intmax_t)t2); assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ assertEqualMem(e + 54, "00000000", 8); /* File size */ - fs = from_hex(e + 54, 8); + fs = (uint64_t)from_hex(e + 54, 8); fs += PAD(fs, 4); assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */ assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */ assert(is_hex(e + 78, 8)); /* rdevmajor */ assert(is_hex(e + 86, 8)); /* rdevminor */ assertEqualMem(e + 94, "00000004", 8); /* Name size */ - ns = from_hex(e + 94, 8); + ns = (uint64_t)from_hex(e + 94, 8); ns += PAD(ns + 2, 4); assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ assertEqualMem(e + 110, "dir\0\0\0", 6); /* Name contents */ @@ -319,14 +322,14 @@ DEFINE_TEST(test_format_newc) "t2=%#08jx", (intmax_t)t, (intmax_t)t2); assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ assertEqualInt(10, from_hex(e + 54, 8)); /* File size */ - fs = from_hex(e + 54, 8); + fs = (uint64_t)from_hex(e + 54, 8); fs += PAD(fs, 4); assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */ assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */ assert(is_hex(e + 78, 8)); /* rdevmajor */ assert(is_hex(e + 86, 8)); /* rdevminor */ assertEqualMem(e + 94, "00000009", 8); /* Name size */ - ns = from_hex(e + 94, 8); + ns = (uint64_t)from_hex(e + 94, 8); ns += PAD(ns + 2, 4); assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ assertEqualMem(e + 110, "hardlink\0\0", 10); /* Name contents */ Modified: stable/12/contrib/libarchive/libarchive/archive_read.c ============================================================================== --- stable/12/contrib/libarchive/libarchive/archive_read.c Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/libarchive/archive_read.c Fri Mar 13 01:05:40 2020 (r358925) @@ -892,15 +892,16 @@ archive_read_data(struct archive *_a, void *buff, size len = a->read_data_remaining; if (len > s) len = s; - if (len) + if (len) { memcpy(dest, a->read_data_block, len); - s -= len; - a->read_data_block += len; - a->read_data_remaining -= len; - a->read_data_output_offset += len; - a->read_data_offset += len; - dest += len; - bytes_read += len; + s -= len; + a->read_data_block += len; + a->read_data_remaining -= len; + a->read_data_output_offset += len; + a->read_data_offset += len; + dest += len; + bytes_read += len; + } } } a->read_data_is_posix_read = 0; Modified: stable/12/contrib/libarchive/libarchive/archive_read_open_filename.c ============================================================================== --- stable/12/contrib/libarchive/libarchive/archive_read_open_filename.c Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/libarchive/archive_read_open_filename.c Fri Mar 13 01:05:40 2020 (r358925) @@ -221,7 +221,9 @@ file_open(struct archive *a, void *client_data) struct read_file_data *mine = (struct read_file_data *)client_data; void *buffer; const char *filename = NULL; +#if defined(_WIN32) && !defined(__CYGWIN__) const wchar_t *wfilename = NULL; +#endif int fd = -1; int is_disk_like = 0; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) @@ -281,10 +283,12 @@ file_open(struct archive *a, void *client_data) #endif } if (fstat(fd, &st) != 0) { +#if defined(_WIN32) && !defined(__CYGWIN__) if (mine->filename_type == FNT_WCS) archive_set_error(a, errno, "Can't stat '%S'", wfilename); else +#endif archive_set_error(a, errno, "Can't stat '%s'", filename); goto fail; Modified: stable/12/contrib/libarchive/libarchive/archive_read_support_format_xar.c ============================================================================== --- stable/12/contrib/libarchive/libarchive/archive_read_support_format_xar.c Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/libarchive/archive_read_support_format_xar.c Fri Mar 13 01:05:40 2020 (r358925) @@ -458,6 +458,11 @@ archive_read_support_format_xar(struct archive *_a) return (ARCHIVE_FATAL); } + /* initialize xar->file_queue */ + xar->file_queue.allocated = 0; + xar->file_queue.used = 0; + xar->file_queue.files = NULL; + r = __archive_read_register_format(a, xar, "xar", @@ -1221,10 +1226,12 @@ heap_add_entry(struct archive_read *a, /* Expand our pending files list as necessary. */ if (heap->used >= heap->allocated) { struct xar_file **new_pending_files; - int new_size = heap->allocated * 2; + int new_size; if (heap->allocated < 1024) new_size = 1024; + else + new_size = heap->allocated * 2; /* Overflow might keep us from growing the list. */ if (new_size <= heap->allocated) { archive_set_error(&a->archive, @@ -1238,9 +1245,11 @@ heap_add_entry(struct archive_read *a, ENOMEM, "Out of memory"); return (ARCHIVE_FATAL); } - memcpy(new_pending_files, heap->files, - heap->allocated * sizeof(new_pending_files[0])); - free(heap->files); + if (heap->allocated) { + memcpy(new_pending_files, heap->files, + heap->allocated * sizeof(new_pending_files[0])); + free(heap->files); + } heap->files = new_pending_files; heap->allocated = new_size; } Modified: stable/12/contrib/libarchive/libarchive/archive_util.c ============================================================================== --- stable/12/contrib/libarchive/libarchive/archive_util.c Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/libarchive/archive_util.c Fri Mar 13 01:05:40 2020 (r358925) @@ -365,6 +365,7 @@ __archive_mktempx(const char *tmpdir, wchar_t *templat } fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR); if (fd == -1) { + la_dosmaperr(GetLastError()); CloseHandle(h); goto exit_tmpfile; } else Modified: stable/12/contrib/libarchive/libarchive/archive_write_disk_posix.c ============================================================================== --- stable/12/contrib/libarchive/libarchive/archive_write_disk_posix.c Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/libarchive/archive_write_disk_posix.c Fri Mar 13 01:05:40 2020 (r358925) @@ -1856,8 +1856,9 @@ finish_metadata: if (a->tmpname) { if (rename(a->tmpname, a->name) == -1) { archive_set_error(&a->archive, errno, - "rename failed"); - ret = ARCHIVE_FATAL; + "Failed to rename temporary file"); + ret = ARCHIVE_FAILED; + unlink(a->tmpname); } a->tmpname = NULL; } @@ -2144,8 +2145,11 @@ restore_entry(struct archive_write_disk *a) if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) && S_ISREG(a->st.st_mode)) { /* Use a temporary file to extract */ - if ((a->fd = la_mktemp(a)) == -1) + if ((a->fd = la_mktemp(a)) == -1) { + archive_set_error(&a->archive, errno, + "Can't create temporary file"); return ARCHIVE_FAILED; + } a->pst = NULL; en = 0; } else { Modified: stable/12/contrib/libarchive/libarchive/archive_write_set_format_xar.c ============================================================================== --- stable/12/contrib/libarchive/libarchive/archive_write_set_format_xar.c Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/libarchive/archive_write_set_format_xar.c Fri Mar 13 01:05:40 2020 (r358925) @@ -681,7 +681,8 @@ xar_write_data(struct archive_write *a, const void *bu { struct xar *xar; enum la_zaction run; - size_t size, rsize; + size_t size = 0; + size_t rsize; int r; xar = (struct xar *)a->format_data; Modified: stable/12/contrib/libarchive/libarchive/cpio.5 ============================================================================== --- stable/12/contrib/libarchive/libarchive/cpio.5 Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/libarchive/cpio.5 Fri Mar 13 01:05:40 2020 (r358925) @@ -244,7 +244,7 @@ Note that this format supports only 4 gigabyte files ( older ASCII format, which supports 8 gigabyte files). .Pp In this format, hardlinked files are handled by setting the -filesize to zero for each entry except the last one that +filesize to zero for each entry except the first one that appears in the archive. .Ss New CRC Format The CRC format is identical to the new ASCII format described Modified: stable/12/contrib/libarchive/libarchive/test/test_read_format_zip.c ============================================================================== --- stable/12/contrib/libarchive/libarchive/test/test_read_format_zip.c Fri Mar 13 00:12:15 2020 (r358924) +++ stable/12/contrib/libarchive/libarchive/test/test_read_format_zip.c Fri Mar 13 01:05:40 2020 (r358925) @@ -916,3 +916,53 @@ DEFINE_TEST(test_read_format_zip_lzma_alone_leak) * suite under Valgrind or ASan, the test runner won't return with * exit code 0 in case if a memory leak. */ } + +DEFINE_TEST(test_read_format_zip_lzma_stream_end) +{ + const char *refname = "test_read_format_zip_lzma_stream_end.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_lzma_stream_end_blockread) +{ + const char *refname = "test_read_format_zip_lzma_stream_end.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} Copied: stable/12/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu (from r358533, head/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu Fri Mar 13 01:05:40 2020 (r358925, copy of r358533, head/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu) @@ -0,0 +1,19 @@ +begin 664 test_read_format_zip_lzma_stream_end.zipx +M4$L#!#\``@`.`#TQD4VJ.XZZ/@(``)`#```%````=FEM)82Q1PWAL +M+U`,N0L_$]^&650C/X$D6#4QFD$\A/"_![4!O/5O/!KH`WCQ*4?T2*]4P#/D +M0'9I?EZG=N69Z0V;H0I=CP*$?".I\ +MGMG/80.A'^W>R4J'S/CZ%P`8`>F=R>R&R$2T@EM#X)"OQH1?A7,`:4IU9WV! +M#2W*DXT',;.4YIN4A:-X)O=IREL201ZSOC=YSAU[C4-::/YV8\)%"L17+>VC +M%/'B]ZCQN$2(Q*9*\KJZ`Y131`]5C&G';@1S-QES_RZF!2OX45@58+??ES%( +MUJ<(\`11M$NO)HK#/MK-9RT"15.2I:IZN8VTM1_?$G\L#BH67]$S%[4 +M%C-$\Q<+./&HV](4,7)OL-@C^M0F"2O!0N$OHOW54H87^QLBQVH*D%A<#SI% +M/#+-5U(W';:KC)RE>0Y^5YI!RECQNR"R4.UW9IR!@:B!UB8?_D5$FT8YCJHJ +M2[2"-&-_D2BJ6#XK[6G=%K"%;'^-+0]FHCY4ER#`^