summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2017-04-25apt-ftparchive: Support '.ddeb' dbgsym packagesUnit 193
(cherry picked from commit c832379bb1163800ed24412fbc19c53eea606a66) (cherry picked from commit 3e26e4e97a6f15bc0fbe16e67aa21165d96a5581)
2017-04-25systemd: Rework timing and add After=network-onlineJulian Andres Klode
The timeout values were so large that the timer could run at any random time of the day, possibly easily interfering with business hours, and causing trouble. Reduce them to 30 minutes of random delay and an accuracy to the default value (1 minute). Also drop the 18:00 event. People still actively use their device during that time, and for servers, there might be less attendance than in the regular 06:00 time slot, so longer time to fix things if something breaks. During a boot, the service might be run to catch up with a timer that would have normally elapsed. Due to no dependencies, it would have run before the network is online - that's bad. Adding an After and a Wants fixes that for boots, but still leaves the same issue for Resume. LP: #1615482 (cherry picked from commit b4f32b13055287d2ac46a08255db475af195b5f7) (cherry picked from commit 6267b47f85588fdd00f6e667598abe52887385ae)
2017-04-25Fix and avoid quoting in CommandLine::AsStringDavid Kalnischkies
In the intended usecase where this serves as a hack there is no problem with double/single quotes being present as we write it to a log file only, but nowadays our calling of apt-key produces a temporary config file containing this "setting" as well and suddently quoting is important as the config file syntax is allergic to it. So the fix is to ignore all quoting whatsoever in the input and just quote (with singles) the option values with spaces. That gives us 99% of the time the correct result and the 1% where the quote is an integral element of the option … doesn't exist – or has bigger problems than a log file not containing the quote. Same goes for newlines in values. LP: #1672710 (cherry picked from commit 2ce15bdeac6ee93faefd4b42b57f035bef80c567) (cherry picked from commit c75620dcfa749f8030e0180df44eec746402885d)
2017-04-25Ignore \.ucf-[a-z]+$ like we do for \.dpkg-[a-z]+$Julian Andres Klode
This gets rid of warnings about .ucf-dist files Reported-By: Axel Beckert (on IRC) (cherry picked from commit 5094697fe4b2459ff6f706a22006d3028369f3fa) (cherry picked from commit 0c42bab8534b4dc95dabdff2a8e08a3574291ec0)
2017-02-27Release 1.2.201.2.20Julian Andres Klode
2017-02-22Don't use -1 fd and AT_SYMLINK_NOFOLLOW for faccessat()Julian Andres Klode
-1 is not an allowed value for the file descriptor, the only allowed non-file-descriptor value is AT_FDCWD. So use that instead. AT_SYMLINK_NOFOLLOW has a weird semantic: It checks whether we have the specified access on the symbolic link. It also is implemented only by glibc on Linux, so it's inherently non-portable. We should just drop it. Thanks: James Clarke for debugging these issues Reported-by: James Clarke <jrtc27@jrtc27.com> (cherry picked from commit 25f54c960d7a4ceca7bd3e21f87baf48d6cbc2d3) (cherry picked from commit 21242490e80dadb167a64c1815c08e1d2258fb61)
2017-02-22Do not package names representing .dsc/.deb/... filesJulian Andres Klode
In the case of build-dep and other commands where a file can be passed we must make sure not to normalize the path name as that can have odd side effects, or well, cause the operation to do nothing. Test for build-dep-file is adjusted to perform the vcard check once as "vcard" and once as "VCard", thus testing that this solves the reported bug. We inline the std::transform() and optimize it a bit to not write anything in the common case (package names are defined to be lowercase, the whole transformation is just for names that should not exist...) to counter the performance hit of the added find() call (it's about 0.15% more instructions than with the existing transform, but we save about 0.67% in writes...). Closes: #854794 (cherry picked from commit 85ee4036c68d8ecd2c973d413a17aca81380900b) (cherry picked from commit 83e6e1a8fc942668f9a01906cb8349fb70a45b3d)
2017-02-22Only merge acquire items with the same meta keyJulian Andres Klode
Since the introduction of by-hash, two differently named files might have the same real URL. In our case, the files icons-64x64.tar.gz and icons-128x128.tar.gz of empty tarballs. APT would try to merge them and end with weird errors because it completed the first download and enters the second stage for decompressing and verifying. After that it would queue a new item to copy the original file to the location, but that copy item would be in the wrong stage, causing it to use the hashes for the decompressed item. Closes: #838441 (cherry picked from commit 7b78e8bef1fc9de22d826db1db9df25f97d3710c) (cherry picked from commit d2749c845954fc1ea38133b050ee49d6f6544235)
2017-02-22COPYING.GPL: Update to recent version (address, LGPL name)Julian Andres Klode
Just copied over from common-licenses. Seems we missed to do that earlier. Gbp-Dch: ignore (cherry picked from commit 84285d17bab32a0ceafe31a5b2be61cc4f520b42) (cherry picked from commit e87c862cbd3aee8200f9752a0023ff53312e6dbd)
2017-02-22travis: Run test suites for root and user in separate build jobsJulian Andres Klode
This hopefully cuts down on the test time. Optimally, we'd just have one build job and parallize, but that requires a tty or something, probably due to GNU parallel? Gbp-Dch: ignore (cherry picked from commit 9b7c71f145e51c2d655ef09fca434d02db08331d) (cherry picked from commit e12dbcbaf486d176762d82f75307b9f5dfa66752)
2017-02-22basehttp: Only read Content-Range on 416 and 206 responsesJulian Andres Klode
This fixes issues with sourceforge where the redirector includes such a Content-Range in a 302 redirect. Since we do not really know what file is meant in a redirect, let's just ignore it for all responses other than 416 and 206. Maybe we should also get rid of the other errors, and just ignore the field in those cases as well? LP: #1657567 (cherry picked from commit 4759a702081297bde66982efed8b2b7fd39ca27c) (cherry picked from commit b5d0e1be09fd07e693bae8046848059f578d029f)
2017-02-22stop rred from leaking debug messages on recovered errorsDavid Kalnischkies
rred can fail for a plentory of reasons, but its failure is usually recoverable (Ign lines) so it shouldn't leak unrequested debug messages to an observing user. Closes: #850759 (cherry picked from commit 2984d7aec37e09b473c7b99f43d20622c25dc99d) (cherry picked from commit d0a345d4a41802e9129b78d70aabd6239a3c651a)
2017-02-22remove 'old' FAILED files in the next acquire callDavid Kalnischkies
If apt renames a file to .FAILED it leaves its namespace and is never touched again – expect since 1.1~exp4 in which "apt clean" will remove those files. The usefulness of these files rapidly degrades if you don't keep the update log itself (together with debug output in the best case) through and on 99% of all system they will be kept around forever just to collect dust over time and eat up space. With this commit an update call will remove all FAILED files of previous runs, so that the FAILED files you have on disk are always only the ones related to the last apt run stopping apt from hoarding files. Closes: 846476 (cherry picked from commit 7ca83492e802967f183babf06ab541b1b51f1703) (cherry picked from commit c8540403ed35fa36e1610fd90aeae8f66c126fdb)
2017-02-22avoid validate/delete/load race in cache generationDavid Kalnischkies
Keeping the Fd of the cache file we have validated around to later load it into the mmap ensures not only that we load the same file (which wouldn't really be a problem in practice), but that this file also still exists and wasn't deleted e.g. by a 'apt clean' call run in parallel. (cherry picked from commit 06606f073210fe3902fe92d5ff77fa1ab621b972) (cherry picked from commit 2e5726edcac4fc9228c6b16281365c3ade189b8b)
2017-02-22don't lock dpkg in update commandsDavid Kalnischkies
The update command acquires a lock on lists/, but at the end it will also require the dpkg/lock while building the binary caches. That seems rather pointless as we are only reading those files, not causing writing in them. This can also cause problems if a package installation is running and a background process (like cron) starts an update: If you are "lucky" enough the update process will pick the dpkg lock in between apt calls causing the installation process to fail. (cherry picked from commit 0d9081598afa051409b03dbdbe5025cd7ce59ba4) (cherry picked from commit b234a610a3818af69952bf85c389588a99b4349f)
2017-02-22don't lock dpkg in 'apt-get clean'David Kalnischkies
We get the archives/lock for clean – that is enough to ensure that other apt instances aren't interfering (or are being interfered with). We don't need to block actions involving dpkg. (cherry picked from commit 22acd327ac39ffe3bb14b3e1f2d1f21761de13ca) (cherry picked from commit e3f9554224c59e1201d00716ef7d7ec046f79f5d)
2017-02-22don't show update stats if cache generation is disabledDavid Kalnischkies
Unlikely that anyone is actually running into this, but if we asked to not generate a cache and avoid it in the first step we shouldn't create one implicitly anyway by displaying the statistics. (cherry picked from commit 33f982b90a4f77be18cb82daf8c79e9c5513761c) (cherry picked from commit 1d017d04c5fdbf71a35e8f154f01bc94305ad798)
2017-02-22use FindB instead of FindI for Debug::pkgAutoRemoveDavid Kalnischkies
Again no practical difference, but for consistency a boolean option should really be accessed via a boolean method rather than an int especially if you happen to try setting the option to "true" … Gbp-Dch: Ignore (cherry picked from commit c15ba854b6736696f164e4d2c243a944e2d4006e) (cherry picked from commit c0dc26456ba74da449eae11c04c3edb3b5f1e35e)
2017-02-22avoid producing invalid options if repo has no hostDavid Kalnischkies
This can happen e.g. for file: repositories. There is no inherent problem with setting such values internally, but its bad style, forbidden in the manpage and could be annoying in the future. Gbp-Dch: Ignore (cherry picked from commit 44ecb8c3579e5ae8828f83530e4151a0ff84d5d6) (cherry picked from commit fec19de5e786564ed8699b38310f7d1a7c348c01)
2017-02-22let {dsc,tar,diff}-only implicitly enable download-onlyDavid Kalnischkies
That was the case already for tar-only and diff-only, but in a more confusing way and without a message while dsc "worked" before resulting in a dpkg-source error shortly after as tar/diff files aren't available… (cherry picked from commit 58ebb3017baf46e33a9bb2c1779d6daede27d108) (cherry picked from commit ab951bc3184d62d9bf9a94187468329e53ac0d0a)
2017-02-22Honour Acquire::ForceIPv4/6 in the https transportLukasz Kawczynski
(cherry picked from commit 49b91f6903804183dbe1abb12ce1f9803a3dee5f) (cherry picked from commit 4034726bfa6d9835bca90c6b4cd276c2fba2aea8)
2017-02-22bash-completion: Only complete understood file paths for installJohn R. Lenton
Previouosly apt's bash completion was such that, given $ mkdir xyzzz $ touch xyzzy.deb xyzzx.two.deb you'd get $ apt install xyzz<tab> xyzzx.two.deb xyzzz/ $ apt install /tmp/foo/xyzz<tab> xyzzx.two.deb xyzzz/ this is inconsistent (xyzzx.two.deb is listed but not xyzzy.deb), but worse than that it offered things that apt would not actually recognise as candidates for install: $ sudo apt install xyzzx.two.deb Reading package lists... Done Building dependency tree Reading state information... Done E: Unable to locate package xyzzx.two.deb E: Couldn't find any package by glob 'xyzzx.two.deb' E: Couldn't find any package by regex 'xyzzx.two.deb' With this small (trival, really) change, apt's bash completion will only offer things apt understands, and won't recquire an aditional period in the filename to offer it: $ apt install xyzz<tab>^C $ # (no completions!) $ apt install ./xyzz<tab> xyzzx.two.deb xyzzy.deb xyzzz/ $ apt install /tmp/foo/xyzz xyzzx.two.deb xyzzy.deb xyzzz/ fixes #28 LP: #1645815 (cherry picked from commit 6761dae5d0c372d132b0df91753120b59e30fd0e) (cherry picked from commit 3c49cc213c9a7747a943419acc2939eb4215b8ef)
2017-02-22show output as documented for APT::Periodic::Verbose 2Paul Wise
The documentation of APT::Periodic::Verbose doesn't match the code, specifically level 2 should apply some things differently to level 1 but does not because it uses `-le 2` instead of `-lt 2` or `-le 1`. Closes: 845599 (cherry picked from commit 250687865e2d27dc949b810e59b07161a4c8f762) (cherry picked from commit c2ce13f26881d7e7ba8b1912c4f358d703fa85a8)
2017-02-22add TMP/TEMP/TEMPDIR to the TMPDIR DropPrivileges danceDavid Kalnischkies
apt tools do not really support these other variables, but tools apt calls might, so lets play save and clean those up as needed. Reported-By: Paul Wise (pabs) on IRC (cherry picked from commit e2c8c825a5470e33c25d00e07de188d0e03922c8) (cherry picked from commit 52067bd0a9e23642b7fa791fb63f4b69cafceb36)
2017-02-22reset HOME, USER(NAME), TMPDIR & SHELL in DropPrivilegesDavid Kalnischkies
We can't cleanup the environment like e.g. sudo would do as you usually want the environment to "leak" into these helpers, but some variables like HOME should really not have still the value of the root user – it could confuse the helpers (USER) and HOME isn't accessible anyhow. Closes: 842877 (cherry picked from commit 34b491e735ad47c4805e63f3b83a659b8d10262b) (cherry picked from commit cc5919076ba1c2dab773a6c06cb3dd5497f0c656)
2017-02-22keep Release.gpg on untrusted to trusted IMS-HitDavid Kalnischkies
A user relying on the deprecated behaviour of apt-get to accept a source with an unknown pubkey to install a package containing the key expects that the following 'apt-get update' causes the source to be considered as trusted, but in case the source hadn't changed in the meantime this wasn't happening: The source kept being untrusted until the Release file was changed. This only effects sources not using InRelease and only apt-get, the apt binary downright refuses this course of actions, but it is a common way of adding external sources. Closes: 838779 (cherry picked from commit 84eec207be35b8c117c430296d4c212b079c00c1) LP: #1657440 (cherry picked from commit 5605c9880f36c764baaca59328777d34645a32fa)
2017-02-22don't install new deps of candidates for kept back pkgsDavid Kalnischkies
In effect this is an extension of the 6 years old commit a8dfff90aa740889eb99d00fde5d70908d9fd88a which uses the autoremover to remove packages again from the solution which are no longer needed to be there. Commonly these are dependencies of packages we end up not installed due to problem resolver decisions. Slightly less common is the situation we deal with here: a package which we wanted to upgrade sporting a new dependency, but ended up holding back. The problem is that all versions of an installed reverse dependencies can bring back a "garbage" package – we need to do this as there is nothing inherently wrong in having garbage packages installed or upgrade them, which itself would have garbage dependencies, so just blindly killing all new garbage packages would prevent the upgrade (and actually generate errors). What we should be doing is looking only at the version we will have on the system, disregarding all old/new reverse dependencies. Reported-By: Stuart Prescott (themill) on IRC (cherry picked from commit 952171787a0b865c17d5c9476e272106383ae93a) (cherry picked from commit 72ea04411b08bb9f25febdc4b4ca8d7b26206f2d) (modified for 1.2.y by adjusting sections in test case)
2017-01-17Release 1.2.191.2.19Julian Andres Klode
2017-01-17test: use downloadfile instead of apthelper download-fileJulian Andres Klode
This prevents CI failures from happening in 1.3 and 1.2 and might actually be more complete. Gbp-Dch: ignore (cherry picked from commit 803dabde5a4345ce83b3d2ffbd475786db9769d9) (cherry picked from commit f55bd828265ff1577533393681dcb82536d402cf)
2017-01-17https: Quote path in URL before passing it to curlJulian Andres Klode
Curl requires URLs to be urlencoded. We are however giving it undecoded URLs. This causes it go completely nuts if there is a space in the URI, producing requests like: GET /a file HTTP/1.1 which the servers then interpret as a GET request for "/a" with HTTP version "file" or some other non-sense. This works around the issue by encoding the path component of the URL. I'm not sure if we should encode other parts of the URL as well, this one seems to do the trick for the actual issue at hand. A more correct fix is to avoid the dequoting and (re-)quoting of URLs when a redirect occurs / a new request is sent. That's been on the radar for probably a year or two now, but nobody bothered implementing that yet. LP: #1651923 (cherry picked from commit 994515e689dcc5f963f5fed58284831750a5da03) (cherry picked from commit 438b1d78b4c33d0a97406f0a7071e3c413dc0aa3)
2016-12-08Release 1.2.18 security update1.2.18Julian Andres Klode
2016-12-08gpgv: Flush the files before checking for errorsJulian Andres Klode
This is a follow up to the previous issue where we did not check if getline() returned -1 due to an end of file or due to an error like memory allocation, treating both as end of file. Here we ensure that we also handle buffered writes correctly by flushing the files before checking for any errors in our error stack. Buffered writes themselves were introduced in 1.1.9, but the function was never called with a buffered file from inside apt until commit 46c4043d741cb2c1d54e7f5bfaa234f1b7580f6c which was first released with apt 1.2.10. The function is public, though, so fixing this is a good idea anyway. Affected: >= 1.1.9 (cherry picked from commit 6212ee84a517ed68217429022bd45c108ecf9f85) (cherry picked from commit e115da452632a024a2885fea27a6c2c5145282b1)
2016-12-08SECURITY UPDATE: gpgv: Check for errors when splitting files (CVE-2016-1252)Julian Andres Klode
This fixes a security issue where signatures of the InRelease files could be circumvented in a man-in-the-middle attack, giving attackers the ability to serve any packages they want to a system, in turn giving them root access. It turns out that getline() may not only return EINVAL as stated in the documentation - it might also return in case of an error when allocating memory. This fix not only adds a check that reading worked correctly, it also implicitly checks that all writes worked by reporting any other error that occurred inside the loop and was logged by apt. Affected: >= 0.9.8 Reported-By: Jann Horn <jannh@google.com> Thanks: Jann Horn, Google Project Zero for reporting the issue LP: #1647467 (cherry picked from commit 51be550c5c38a2e1ddfc2af50a9fab73ccf78026) (cherry picked from commit 4ef9e0837ce139b398299431ae2294882f531d8e)
2016-11-23Release 1.2.171.2.17Julian Andres Klode
2016-11-23show apt-key warnings in apt updateDavid Kalnischkies
In 105503b4b470c124bc0c271bd8a50e25ecbe9133 we got a warning implemented for unreadable files which greatly improves the behavior of apt update already as everything will work as long as we don't need the keys included in these files. The behavior if they are needed is still strange through as update will fail claiming missing keys and a manual test (which the user will likely perform as root) will be successful. Passing the new warning generated by apt-key through to apt is a bit strange from an interface point of view, but basically duplicating the warning code in multiple places doesn't feel right either. That means we have no translation for the message through as apt-key has no i18n yet. It also means that if the user has a bunch of sources each of them will generate a warning for each unreadable file which could result in quite a few duplicated warnings, but "too many" is better than none. Closes: 834973 (cherry picked from commit 29c590951f812d9e9c4f17706e34f2c3315fb1f6)
2016-11-23test-releasefile-verification: installaptold: Clean up before runJulian Andres Klode
This is needed to make it possible to use installaptold multiple times in a test case. (originally part of commit 46e00c9062d09a642973e83a334483db1f310397)
2016-11-23apt-key: warn instead of fail on unreadable keyringsDavid Kalnischkies
apt-key has inconsistent behaviour if it can't read a keyring file: Commands like 'list' skipped silently over such keyrings while 'verify' failed hard resulting in apt to report cconfusing gpg errors (#834973). As a first step we teach apt-key to be more consistent here skipping in all commands over unreadable keyrings, but issuing a warning in the process, which is as usual for apt commands displayed at the end of the run. (cherry picked from commit 105503b4b470c124bc0c271bd8a50e25ecbe9133) (removed the buffering of warnings in aptwarnings.log, as we do not have a cleanup function where we can cat it) LP: #1642386
2016-11-15Release 1.2.161.2.16Julian Andres Klode
2016-11-14Release 1.2.16 RC1Julian Andres Klode
2016-11-14Revert "if the FileFd failed already following calls should fail, too"Julian Andres Klode
This reverts commit 1b63558a39ee1eed7eb024cd0e164d73beb165b1. This commit caused a regression in the unit tests: The error was propagated to Close(), where we expected it to return true.
2016-11-14Add shippable.yml for CI on ShippableJulian Andres Klode
This uses the current Ubuntu 16.04 for testing, but it only runs one run, presumably as root. (adapted from commit bb315d0513b93ef111ea69106d00188f0a4ec17a)
2016-11-14travis: Pull in c++ standard library and g++ 5 from wilyJulian Andres Klode
The one in trusty does not support std::put_time(), causing the compile to fail. This commit is specific to the 1.2 branch, as newer branches already pull this in automatically. Gbp-Dch: ignore
2016-11-14Use C locale instead of C.UTF-8 for protocol stringsJulian Andres Klode
The C.UTF-8 locale is not portable, so we need to use C, otherwise we crash on other systems. We can use std::locale::classic() for that, which might also be a bit cheaper than using locale("C"). (cherry picked from commit 0fb16c3e678044d6d06ba8a6199b1e96487ee0d8)
2016-11-14imbue .diff/Index parsing with C.UTF-8 as wellDavid Kalnischkies
In 3bdff17c894d0c3d0f813d358fc45d7a263f3552 we did it for the datetime parsing, but we use the same style in the parsing for pdiff (where the size of the file is in the middle of the three fields) so imbueing here as well is a good idea. (cherry picked from commit 1136a707b7792394ea4b1d039dda4f321fec9da4)
2016-11-14prevent C++ locale number formatting in text APIs (try 3)David Kalnischkies
This time it is the formatting of floating numbers in progress reporting with a radix charater potentially not being dot. Followup of 7303e11ff28f920a6277c159aa46f80c007350bb. Regression of b58e2c7c56b1416a343e81f9f80cb1f02c128e25 in so far as it exchanging very effected with slightly less effected code. LP: 1611010 (cherry picked from commit 0919f1df552ddf022ce4508cbf40e04eae5ef896)
2016-11-14prevent C++ locale number formatting in text APIs (try 2)David Kalnischkies
Followup of b58e2c7c56b1416a343e81f9f80cb1f02c128e25. Still a regression of sorts of 8b79c94af7f7cf2e5e5342294bc6e5a908cacabf. Closes: 832044 (cherry picked from commit 7303e11ff28f920a6277c159aa46f80c007350bb)
2016-11-14imbue datetime parsing with C.UTF-8 localeDavid Kalnischkies
Rewritten in 9febc2b238e1e322dce1f94ecbed46d595893b52 for c++ locales usage and rewritten again in 1d742e01470bba27715a8191c50adde4b39c2f19 to avoid a currently present stdlibc++6 bug in the std::get_time implementation. The later implementation uses still stringstreams for parsing, but forgot to explicitly reset the locale to something sane (for parsing english dates that is), so date and especially the parsing of a number is depending on the locale. Turns out, the French (among others) format their numbers with space as thousand separator so for some reason the stdlibc++6 thinks its a good idea to interpret the entire datetime string as a single number instead of realizing that in "25 Jun …" the later parts can't reasonably be part of that number even through there are spaces there… Workaround is hence: LC_NUMERIC=C.UTF-8 Closes: 828011 (cherry picked from commit 3bdff17c894d0c3d0f813d358fc45d7a263f3552)
2016-11-14avoid std::get_time usage to sidestep libstdc++6 bugDavid Kalnischkies
As reported upstream in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71556 the implementation of std::get_time is currently not as accepting as strptime is, especially in how hours should be formatted. Just reverting 9febc2b238e1e322dce1f94ecbed46d595893b52 would be possible, but then we would reopen the problems fixed by it, so instead I opted here for a rewrite of the parsing logic which makes this method a lot longer, but at least it provides the same benefits as the rewrite in std::get_time was intended to give us and decouples us from the fix of the issue in the standard library implementation of GCC. LP: 1593583 (cherry picked from commit 1d742e01470bba27715a8191c50adde4b39c2f19)
2016-11-14accept only the expected UTC timezones in date parsingDavid Kalnischkies
HTTP/1.1 hardcodes GMT (RFC 7231 §7.1.1.1) and what is good enough for the internet must be good enough for us™ as we reuse the implementation internally to parse (most) dates we encounter in various places like the Release files with their Date and Valid-Until header fields. Implementing a fully timezone aware parser just feels too hard for no effective benefit as it would take 5+ years (= until LTS's are out of fashion) until a repository could use non-UTC dates and expect it to work. Not counting non-apt implementations which might or might not only want to encounter UTC here as well. As a bonus, this eliminates the use of an instance of setlocale in libapt. Closes: 819697 (cherry picked from commit 9febc2b238e1e322dce1f94ecbed46d595893b52)
2016-11-14use de-localed std::put_time instead rolling our ownDavid Kalnischkies
(cherry picked from commit eceb219c2a64f3f81421c3c6587380b6ae81a530)