Debian Package Tracker
Register | Log in
Subscribe

httrack

Copy websites to your computer (Offline browser)

Choose email to subscribe with

general
  • source: httrack (main)
  • version: 3.50.2-1
  • maintainer: Xavier Roche (DMD)
  • arch: all any
  • std-ver: 4.7.4
  • VCS: Git (Browse, QA)
versions [more versions can be listed by madison] [old versions available from snapshot.debian.org]
[pool directory]
  • o-o-stable: 3.49.2-1.1
  • oldstable: 3.49.4-1
  • stable: 3.49.6-1
  • testing: 3.50.2-1
  • unstable: 3.50.2-1
versioned links
  • 3.49.2-1.1: [.dsc, use dget on this link to retrieve source package] [changelog] [copyright] [rules] [control]
  • 3.49.4-1: [.dsc, use dget on this link to retrieve source package] [changelog] [copyright] [rules] [control]
  • 3.49.6-1: [.dsc, use dget on this link to retrieve source package] [changelog] [copyright] [rules] [control]
  • 3.50.2-1: [.dsc, use dget on this link to retrieve source package] [changelog] [copyright] [rules] [control]
binaries
  • httrack
  • httrack-doc
  • libhttrack-dev
  • libhttrack3
  • proxytrack
  • webhttrack
  • webhttrack-common
action needed
26 new commits since last upload, is it time to release? normal
vcswatch reports that this package seems to have new commits in its VCS but has not yet updated debian/changelog. You should consider updating the Debian changelog and uploading this new version into the archive.

Here are the relevant commit logs:
commit d4fc328b4f0dd1ba0b3c8b71d12ad9bbbb06025e
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 20:31:41 2026 +0200

    A refused allocation loses the buffer the charset converters were growing (#1703)
    
    `realloct` in `src/htssafe.h` is a plain `realloc` alias. A site that
    assigns its result back over the pointer it passed in loses the old
    block when the allocation fails. Five places did that.
    `src/htsselftest.c`'s hashtable reader then used the NULL it had just
    stored.
    
    Four of them now `assertf`. The exported `hts_convertStringToUTF8` must
    not kill its embedder, per #1688. So the two sites it reaches through
    `hts_convertStringCharset` free the buffer and return NULL, and
    `src/htscharset.h` says so at the declaration. Two siblings on the same
    helper get that for free.
    
    `-#test=ucs4-oom` starves the growth under `RLIMIT_AS` and requires an
    abort. It covers `INCREASE_CAPA()` alone. A 1 MiB cap also breaks
    iconv's gconv module load, and the probe would read that legitimate
    "charset not found" return as a missing abort.
    
    Closes #1705
    
    Finding originally reported by @sparktron in #1693 (closed).
    
    ---------
    
    Signed-off-by: Xavier Roche <xroche@gmail.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 13eaf0453dc0faf88c40cb7302993298b091cbee
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 19:37:48 2026 +0200

    The SIGPIPE self-test fails on macOS when the socket reset arrives late (#1711)
    
    `471_engine-sigpipe.test` failed twice in 17 macOS arm64 runs, and never
    on Linux. The self-test resets the peer socket, writes 64 times, and
    requires one of those writes to fail, but nothing waits for the reset to
    arrive. macOS hands loopback input to its own thread. On a loaded 3-core
    runner all 64 writes can finish before the kernel processes the RST, and
    then none of them fails. Linux drains that backlog in the sending
    thread, which is why only macOS saw this.
    
    The self-test now waits up to 10 seconds for the socket to report the
    reset. It consumes the `ECONNRESET` with a read, then requires the next
    write to fail.
    
    Three mutants still red the test:
    
    - `sendc()` without `HTS_MSG_NOSIGNAL` dies on SIGPIPE.
    - `sendc()` that reports success on a failed write aborts.
    - A peer that is never reset reds after the 10-second bound rather than
    hanging.
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 4eb206eb08e60c602bd6c8a5fc967140327d34b5
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 18:20:15 2026 +0200

    A robots.txt group naming httrack never ends when the `*` group comes after it (#1702)
    
    When a site writes a `User-agent: httrack` group and then a `User-agent:
    *` group, httrack obeyed both. `robots_parse()` reset the group only
    when it was not already locked to ours, so the wildcard group's
    `Disallow` lines were appended to ours. Pages the site allows us were
    skipped, and nothing in the log said so. RFC 9309 2.2.1 makes the groups
    exclusive: once a group names us, no generic group applies.
    
    The parser now tracks where a group ends. A user-agent line that follows
    a rule line opens a new group, and consecutive user-agent lines name one
    group. The same rule fixes two cases where master crawled what the site
    had forbidden us. A second agent name on our group discarded that group,
    and two groups both naming us kept only the last. So the bug runs in
    both directions.
    
    A blank line does not end a group. RFC 9309's ABNF allows an empty line
    inside the user-agent run, and Google's reference parser agrees. So
    `User-agent: httrack`, a blank line, then `User-agent: *` is one group,
    and its rules do bind us. An assertion pins it, since that is the case
    most likely to be read the other way.
    
    The fixture disallows `/secret` for httrack and `/public` for everyone.
    The master binary mirrors neither page, the fixed one mirrors
    `/public/page.html`. `st_robots()` gains the group orderings it was
    missing. Five of its new assertions fail on master, and it catches four
    mutants, one of which wrongly starts allowing rather than blocking. No
    existing assertion had to be inverted.
    
    Closes #1695
    
    Finding originally reported by @sparktron in #1693 (closed).
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 771e838e640da0a27c8cf82d4fed8e9b7734426e
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 17:14:46 2026 +0200

    Two worker threads that fail at the same time print each other's error message (#1707)
    
    `strerror()` answers with a buffer the caller does not own. The engine
    calls it on the socket, cache and logging paths, all of which run on
    crawler workers.
    
    `hts_strerror()` now copies the message into the caller's buffer through
    `strerror_r()`, or through `strerror_s()` on MSVC. Which `strerror_r` is
    in scope is decided in C on `__USE_GNU`, not by `AC_FUNC_STRERROR_R`.
    That probe defines `_GNU_SOURCE`, while `htsglobal.h` reaches
    `<stdio.h>` before `config.h`, so the tree always compiles against the
    XSI one and the two answers disagree. A MinGW build has neither form and
    keeps plain `strerror()`. The self-test says so when it runs there.
    
    Separately, a `--disable-ipv6` build resolves with `gethostbyname()`,
    whose `struct hostent` is shared, and every resolve runs on its own
    worker thread. That call and the copy out of it now run under one lock.
    The arm cannot use `getaddrinfo()`, because configure also defines
    `HTS_INET6` as 0 when libc has none.
    
    `-#test=strerror` drives eight threads and eight codes. No CI leg
    compiles the resolver arm, so the test guards that one at the source.
    `htsweb.c` keeps its one-shot `strerror()`, because `htsserver` links
    the library and `hts_strerror` is hidden.
    
    Closes #1697
    
    Finding originally reported by @sparktron in #1693 (closed).
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 322838fb65bbf5ac653c1816244712f058250a96
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 16:44:11 2026 +0200

    The --catchurl capture proxy listens on the LAN address, not on this machine only (#1701)
    
    `httrack --catchurl` opens a throwaway proxy so the user can point a
    browser at it and hand the engine a URL, cookies and all.
    `catch_url_init()` bound it to whatever address `gethostname()` resolved
    to, which on most machines is the LAN or the public address. Anyone who
    can reach that port can take the slot before the browser does.
    
    It now binds `127.0.0.1`, and the address printed as "Proxy's address"
    follows it, so the browser still finds the proxy. No IPv6 is lost.
    `hts_dns_resolve_nocache()` takes the first `getaddrinfo` result, so on
    a dual-stack host the old code bound the global v6 address rather than
    `::1`.
    
    The port was read from the requested address rather than the bound one,
    so the ephemeral fallback in `catch_url_init_std()`'s port list reported
    0. It comes from `getsockname()` now.
    
    The new `catchurl-bind` self-test, in test 438, checks both entry points
    and captures a request over the socket. The `--disable-ipv6` build was
    checked too.
    
    Finding originally reported by @sparktron in #1693 (closed).
    
    Closes #1696
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit f82c11bf1d114fe2a1454a71bac4d7f5864f5e9f
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 16:35:11 2026 +0200

    A cache repair writes to a file it failed to open (#1699)
    
    `unzRepair()` in the vendored `src/minizip/mztools.c` opens three files:
    the damaged archive, the repaired archive, and a temporary file for the
    central directory. It checks the first two and writes to the third
    regardless, so a failed third open sends every central-directory
    `fwrite` through a NULL `FILE*`. That same `else` branch leaves the
    handles that did open unclosed. `cache_repair()` runs it whenever
    `hts-cache/old.zip` fails to open, so a corrupt cache plus a descriptor
    shortage is enough.
    
    I reproduced the crash at `mztools.c:165` with an uncreatable temporary
    path, and again with `RLIMIT_NOFILE` lowered. The fix checks the third
    handle, then closes what opened and removes the partial files. Upstream
    minizip does not remove them. Every path here is engine-owned scratch,
    but another caller could lose a file it owns.
    
    The new `-#test=zip-repair-openfail` self-test fails each of the three
    opens in turn and checks that nothing is left behind and no descriptor
    leaks. `mztools.c.diff` is regenerated, or the next re-sync from
    upstream drops the fix.
    
    Closes #1698
    
    Finding originally reported by @sparktron in #1693 (closed).
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 024123c567bbb78cf34c9ba3fa4048f832f4252b
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 11:30:09 2026 +0200

    libhttrack can kill its host process with SIGPIPE (#1691)
    
    Only `httrack.c`, `htsserver.c` and `htsweb.c` ever set a SIGPIPE
    disposition, so every other embedder died on a write to a peer that had
    gone. The FreeBSD canary found it through `tests/mirrorverdict`.
    
    A library must not touch its host's signals, so this stops raising the
    signal rather than swallowing it. `HTS_MSG_NOSIGNAL` goes on every
    `send()`, `SO_NOSIGPIPE` on every socket we write to, and a
    thread-scoped mask around the four OpenSSL calls that write. Each covers
    a gap the others leave: Linux has no such socket option, and macOS lacks
    `MSG_NOSIGNAL`, which OpenSSL's own `write(2)` never sees anyway.
    
    The mask drains with `sigtimedwait()`, because `sigwait()` hangs for
    good when another thread takes a process-directed SIGPIPE first. Darwin
    has no `sigtimedwait` and does have `SO_NOSIGPIPE`, so the mask is a
    no-op there.
    
    A custom OpenSSL BIO was the other candidate. It works, but
    `BIO_meth_get_*` is absent under the `-DOPENSSL_NO_DEPRECATED` leg we
    build, so it costs 86 lines reimplementing `bss_sock.c` on the
    non-blocking crawl path.
    
    `-#test=sigpipe` restores the default action before it writes, which is
    what lets a regression reach the test as a signal. Six mutants kill it,
    and two source checks name any OpenSSL call that loses its mask or any
    `send()` that loses the flag.
    
    Closes #1689
    
    ---------
    
    Signed-off-by: Xavier Roche <xroche@gmail.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 6eb345cba9fbcdd1519207a1a62c8f15875fbeb2
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 10:15:04 2026 +0200

    Tests 436, 445 and 459 throw away the engine log that names why a mirror stopped (#1692)
    
    Three WSL2 jobs since 10 September left a four-line crawl log and
    nothing else, stopping at `Mirror not completed (see log file)`. The
    engine prints that line whenever a mirror did not complete, and it
    points at `hts-log.txt` for the reason. Test 436 dumps the crawl log and
    then removes the output directory, so the file it names is gone. Tests
    445 and 459 drop the same engine log.
    
    Left alone the same crawl completes and prints `Done.`, so
    `--timeout=30` does not reap a two-byte-a-second transfer. Pointing the
    arm at a dead port reproduces the four lines, and `hts-log.txt` then
    names `"Connect Error" (-4)` on the seed.
    
    The three tests now dump the engine log beside the crawl log. Test 436
    also waits for a trickle page to start transferring before it asks for
    the abort. A mirror that ends before any transfer starts fails on that
    wait, and the dump carries the reason.
    
    Closes #1680
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 27d068e26a8db2bbf3bc4f9b8606bbce18321c9b
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 06:21:18 2026 +0200

    The FreeBSD canary builds with base make and keeps two gaps it has closed (#1690)
    
    Four things red this weekly job, and only the last is an engine bug.
    
    The prepare step symlinks gmake over `/usr/local/bin/make`, but the
    login PATH puts `/usr/bin` first, so every run so far built with base
    make. Test 397 noticed, because its `ifeq` fixture is GNU make syntax.
    The port builds with gmake, so `build.sh` now puts `/usr/local/bin`
    first.
    
    144 and 215 leave the known list. #1507 gave `hts_self_path` a BSD arm,
    and the canary reds on a known entry that passes again.
    
    Test 257 gated a block on `test -d /proc`, and FreeBSD ships `/proc`
    empty, so the read failed. Test 425 looked up `bash` in `/usr/bin` and
    `/bin`, and FreeBSD keeps it in `/usr/local/bin`. Each now tests what it
    is about to use.
    
    470 still fails, and the test discarded mirrorverdict's exit status so
    it could not say why. It now names the signal, which is SIGPIPE, filed
    as #1689.
    
    Dispatched on this branch the canary passes 445 of 492, up from 443,
    without 257, 397 or 425 among its failures.
    
    ---------
    
    Signed-off-by: Xavier Roche <xroche@gmail.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 6de3ed40ed294c087d7e48994875b05015f932ca
Author: Xavier Roche <roche@httrack.com>
Date:   Thu Sep 17 06:21:15 2026 +0200

    The drift canary dies when a packager deletes a patch it watches (#1688)
    
    Termux deleted all six patches it carried over this tree in its 3.50.1
    bump, which is the outcome we asked them for. The canary has been red on
    it since 9 September, because `carried_patch` fetched each patch through
    `fetch`, which aborts the run on any curl failure.
    
    A deleted patch is now a finding that says "prune this check", the way
    `expect` already treats a premise that is gone. Any other HTTP status
    still aborts, so an unreachable host cannot read as a dropped patch. The
    check floor drops from 21 to 15 with the six Termux ids.
    
    `./bootstrap` was in the workflow only for those patches, which targeted
    generated files. Nothing left in the table reads a build product, so
    that step and the autotools install go with it.
    
    The script now runs 15 checks and exits 0. Against live URLs a 404
    reports DRIFT, a 500 still aborts, and an empty 200 still aborts.
    
    ---------
    
    Signed-off-by: Xavier Roche <xroche@gmail.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit d75873b39dfd9858df141fbc9bdfb242980bd469
Author: Xavier Roche <roche@httrack.com>
Date:   Wed Sep 16 10:52:46 2026 +0200

    The mirror footer is built with unbounded sprintf into a fixed buffer (#1686)
    
    The mirror footer is a fixed `char[8192]` that seven successive
    `sprintf(finalInfo + strlen(finalInfo), ...)` calls appended to, none of
    which could see the end of the buffer. `infoupdated[256]` was written
    the same way. The widest possible footer is under 800 bytes, so nothing
    reaching it today can overflow it. This is hardening, not a fix.
    
    `-Wformat-truncation` fires only on a bounded `snprintf` whose return is
    discarded. An unbounded `sprintf` never reaches compiler output, so a
    pass scoped off warnings misses this function entirely.
    
    The appends go through `slcatprintfbuff_clip()`, added beside
    `slprintfbuff_clip()` in `htssafe.h`. That family already has this shape
    for text meant to be clipped rather than dropped whole. It shares
    `vslprintfbuff()` as its engine, so it inherits the `dest[size - 1]`
    terminator that pre-C99 `_vsnprintf` needs. `infoupdated` moves to
    `slprintfbuff_clip()` for the same reason, because `_WIN32` rewrites
    `snprintf` to `_snprintf`.
    
    The footer text does not change. The same crawl through this build and
    through master gives byte-identical footers. That was checked on a plain
    run, an aborted run, both arms of an update, compression stats and
    keep-alive.
    
    The compression-ratio and requests-per-connection lines are in no test.
    That predates this change, which only routes them through a checked
    helper.
    
    Closes #1685
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit f6426310d8bbbd376dac70bffe444b1d147bfc06
Author: Xavier Roche <roche@httrack.com>
Date:   Tue Sep 15 19:48:28 2026 +0200

    A mirror run with no log file reports zero errors, however many it hit (#1683)
    
    `stat_errors`, `stat_warnings` and `stat_infos` counted log lines. A
    front end that turns the log file off read 0 errors after a crawl where
    every link failed. httrack-android emits `-Q` for that and its finish
    pane printed `Success! (0 errors)`.
    
    `hts_log_vprint()` now runs the level test above the `opt->log` gate and
    counts the event there. Counts are unchanged when a log file is open,
    because counting still happens after the verbosity filter.
    
    The counting moved out of `fspc()` into `fspc_count()` rather than
    losing its `fp != NULL` guard. `fp == NULL` is `fspc()`'s read path, so
    an unguarded increment would count every read, and `hts_get_stats()` is
    polled during a mirror. The self-test pins that.
    
    A panic now counts as an error. `LOG_PANIC` mapped to a string no
    counter matched, so a mirror that died on a fatal condition also
    published 0 errors. That changes `stat_errors` for runs that panic, with
    or without a log file.
    
    Found by the httrack-android session while reviewing its PR #221.
    
    Closes #1681
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 12706f4b62234750d4f61983418875431afe9396
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Tue Sep 15 16:50:01 2026 +0000

    Bump github/codeql-action from 4.37.9 to 4.38.0 (#1679)

commit 6f46e95632ec4c14a78cca1d8f55fe4b4cca799f
Author: Xavier Roche <roche@httrack.com>
Date:   Tue Sep 15 18:12:27 2026 +0200

    Test 258 removes a directory with rm -rf, which drvfs leaves half-done (#1682)
    
    The last case of `258_crawllib.test` removes the crawl output while
    `write_lock_request` retries, and expects the helper to name the
    removal. On the WSL2 Windows leg, `rm -rf` deletes the contents and
    leaves the directory behind (#1639). The blocking child went with it, so
    the retry wrote the request, and the case failed for a removal it never
    saw. Both open dependabot bumps went red on it on 15 September, while
    master passed.
    
    A rename takes the directory in one step, so nothing survives for the
    write to land in. Control: with the helper's removal check dropped, the
    case still fails.
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit c95e91ac54f00bed3467b80a64a75580279ca62a
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Tue Sep 15 15:59:13 2026 +0000

    Bump vmactions/freebsd-vm from 1.5.5 to 1.5.6 (#1678)

commit 9b15ccd0ff479da817ee99044d9e50aa8c5658bb
Author: Xavier Roche <roche@httrack.com>
Date:   Tue Sep 15 13:51:55 2026 +0200

    A front end cannot tell a link the server refused from one whose transfer failed (#1676)
    
    A front end cannot tell a link the server refused from one whose
    transfer failed. `stat_errors` counts LOG_ERROR log lines, so a 404 and
    a timeout differ only in a number. `-Q` writes no log and leaves it at
    zero. An Android crawl firewalled by Doze times out on every link and
    reports success over a holed mirror. WinHTTrack and WebHTTrack share the
    blind spot.
    
    This adds a per-mirror count of links given up on a failed transfer,
    published as `stat_transport_failures` beside `stat_errors`. It keys on
    `back_transfer_failed()`, the classifier the engine already uses for
    that decision. robots.txt is excluded, because a host that never
    answered it has lost no content.
    
    Two things a reader should know. The count includes a body cut off after
    a `200`, because the engine gives that the same status code as a refused
    connection. No predicate on the code can separate them. A GUI polling
    the loop callback sees the count only while the crawl continues past the
    failure. A front end deciding at the end should read it there.
    
    Both structs take a tail append and no member moves, measured by diffing
    `offsetof` tables. `HTS_STAT` is an exported object and grows with it,
    from 168 to 176 bytes. No installed header declares it, so reaching it
    takes a hand-written extern. That is the exposure to weigh against the
    ruling that no soname bump is needed.
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit f4ee93c3f55e6f959cc755c546232d91aeaca0e0
Author: Xavier Roche <roche@httrack.com>
Date:   Mon Sep 14 09:13:25 2026 +0200

    Tests 436 and 459 give up when one write into their crawl directory is refused (#1675)
    
    Three WSL2 jobs failed in `436_local-abort-lock` since 10 September, in
    runs 34447609795, 34451707795 and 34487486427. Each was the only failing
    test in its job, and all three report the same failure. A write of
    `hts-abort.lock` into the crawl output directory was refused while that
    directory was still there. The wait one line above had just read a file
    inside it.
    
    The review of PR #1631 dropped a retry here, because the evidence then
    could not say whether anything had removed the directory. The walk added
    by #1650 has now answered that. The helper retries for three seconds,
    and reads the directory again after each failed write, so a removal is
    named rather than waited out. It prints the try that landed on stderr,
    which the Windows job uploads with the test log.
    
    Test 258 covers three cases: the retry landing, the retry running out,
    and a removal during the retries.
    
    This is a mitigation and not a fix. Nothing here explains why drvfs
    refuses a write into a directory it holds, and no upstream ticket is
    filed. Two of the three jobs also show that the engine had ended its
    mirror by the time of the failure. That is unexplained, and it belongs
    on the issue.
    
    Closes #1639
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 5f71d45c689138486a5db281ea786a8e6b48421d
Author: Xavier Roche <roche@httrack.com>
Date:   Sun Sep 13 20:53:37 2026 +0200

    httrack-android cannot see the -#c crash-test markers (#1673)
    
    The two `-#c` markers went to stderr only. httrack-android recovers a
    worker fault through coffeecatch, and it reads the engine's log callback
    rather than stderr. So it cannot tell a deliberate crash test from a
    real crash.
    
    Both markers now also go to `hts_log_vprint(NULL, LOG_ERROR, ...)`. NULL
    matters, because the callback runs before the `opt != NULL` guard. A
    worker reaches the front end's log without touching opt, which is what
    the recovery design needs. A front end that captures both channels sees
    the marker twice.
    
    `01_engine-crash-announce` checks stderr, then arms a real `-#c=dnssegv`
    and faults, so both markers are checked on the path Android recovers.
    Reverting either call site fails it.
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 5108864f3d978f7a964c4520628b8ba91b9973cd
Author: Xavier Roche <roche@httrack.com>
Date:   Sun Sep 13 20:36:41 2026 +0200

    A WSL2 interop outage reads as failing tests on the Windows leg (#1674)
    
    When WSL2's `init` cannot reach the Windows side it writes
    `UtilAcceptVsock:235: accept4 failed 110` and `httrack.exe` never
    launches. Whichever tests called it read empty output and reported it as
    a content failure of their own. PR #1672 collected three unrelated reds
    that way, and they looked like a buffer bug.
    
    The driver now reads the failing tests' own logs for that line. When
    every failure carries it, the leg ends on 3. That is the status a lost
    worker already ends on, and it means repeat this leg rather than
    investigate it. The failing tests are still named either way, so an
    outage cannot hide a real red that picked the line up for another
    reason.
    
    Test 469 covers the verdict, test 337 the driver's gate.
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 03d67612dc1c1ffc64d8ed7c6c6fb883b87e3191
Author: Xavier Roche <roche@httrack.com>
Date:   Sat Sep 12 18:26:59 2026 +0200

    -#c cannot fault a live worker, so the recovery path is unreachable (#1672)
    
    `-#c=threadsegv` and `-#c=threadstack` cannot reach the engine's
    fault-recovery path. The pre-pass runs the kind, then frees the option
    set and returns −1 before any mirror starts. So there is no crawl
    thread, and no engine worker to fault. A front end installs
    `hts_set_thread_runner()` to recover a worker fault. Verifying #1671 on
    a device took two hand-patched worker bodies for want of a way in.
    
    `-#c=dnssegv` and `-#c=ftpsegv` arm a fault instead of taking one, and
    the pre-pass lets the command line through so the mirror runs into it.
    The resolver worker faults with its answer in hand and not yet
    published. The FTP worker faults with its backlog slot already
    registered. Those are the two states worth recovering from.
    
    The option parser gains a `#c` case, because an armed kind now reaches
    it.
    
    Test 468 asserts what no other kind can: the project directory is on
    disk when the fault lands, so the mirror was running. It resolves the
    trace through addr2line to check the fault came from the worker's own
    function, and it reads the signal by name. Its control is `-#c=segv`,
    which leaves no project behind. Six mutants turn it red, one by arming
    the control's own kind.
    
    The httrack-android session asked for this, to replace its patches.
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit a9bdf1c8ad6b0b9287cc09dc3c98fbe2cbbc3972
Author: Xavier Roche <roche@httrack.com>
Date:   Sat Sep 12 13:07:29 2026 +0200

    The crawl waits forever for an FTP worker a crash recovery cut short (#1671)
    
    A crawl could hang forever at teardown. `back_launch_ftp()` took its
    worker off the live-worker list on its last line. `ftp_stop_workers()`
    polls for an empty list with no bound, so a worker that never reached
    that line wedged the crawl thread.
    
    A worker reaches it unless something cut its body short, which is what a
    front end's thread runner does. httrack-android now installs one through
    coffeecatch, to catch a crash signal on an engine worker and recover
    from it instead of dying.
    
    The thread layer now runs a tail callback once the body is over, whether
    or not the body got there. FTP hands its slot back from that tail, and
    the DNS resolver releases its job there.
    
    A worker is not resumable after a crash, so the mirror ends rather than
    failing the one link. The thread layer raises a flag, and the crawl
    thread turns it into `HTS_EXIT_MIRROR_ABORTED`, being the only thread
    that may touch `opt`. A worker carries the round it was spawned in, so
    one an earlier mirror abandoned cannot abort this one.
    
    Three selftests and seventeen mutants cover it. Two older paths dropped
    that exit status on the way out, and one of them also swallowed the
    cache-write abort.
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 0ae7bcdb5e9f11281ccaee86973c84444d8fd442
Author: Xavier Roche <roche@httrack.com>
Date:   Fri Sep 11 19:38:49 2026 +0200

    Test 250 reads an exited process as still running on GNU/Hurd (#1668)
    
    3.50.2-1 failed to build on hurd-amd64 and hurd-i386, and
    `250_timeout-poll-nofork` was the only failure on both. 3.50.1-1 built,
    so this is a regression from #1554, which added `pid_is_zombie`.
    
    Neither of that helper's two routes works on GNU/Hurd. Its procfs builds
    `/proc/PID/stat` out of Mach data an exited process no longer has, so
    the read fails where Linux answers `Z`. The fallback `ps -o state= -p
    PID` fails too, because Hurd's `ps` rejects `-p` and takes the pid
    positionally. `kill -0` then keeps succeeding on the zombie until the
    grace runs out.
    
    The fix is the second of those. Hurd's `ps` does know the state, from
    proc-info, which a zombie still carries, so `pid_state` now tries both
    spellings and takes whatever the host says.
    
    Four earlier drafts of this branch tried instead to read the failure
    itself as proof of death, and review broke each one. The last one shows
    why none of them could work. `/proc/PID/stat` needs `PSTAT_THREAD_WAIT`,
    libps sets that only while the message port is usable, and
    `should_suppress_msgport` turns it off for a suspended task. A live
    process that is merely stopped reads EIO on Hurd, so no test on the file
    can tell it from a dead one.
    
    `pid_state_readable` rests on the same answer, which is what it always
    claimed to report. A host neither route answers for now makes the test
    skip rather than assert. The guard also runs after the kill now, because
    asking about a live process is how the state Hurd cannot report came to
    be graded.
    
    One fix here is older than the branch. Linux writes `comm` into
    `/proc/PID/stat` unescaped. A process named `") Z<LF>q"` therefore
    splits the file, and the first line ends in a state it is not in.
    Reading one line reported `Z` for a sleeping process.
    
    `pid_state` takes one row from `ps` or none. A header, or an answer
    covering several pids, says nothing about this one, and folding the rows
    together invents a state no column held.
    
    Fourteen mutants of the helper each fail a test, one of them a stderr
    leak an earlier draft left behind.
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 45e28c1876ecfeab23bb5209a59986b128a2e5e8
Author: Xavier Roche <roche@httrack.com>
Date:   Fri Sep 11 16:44:02 2026 +0200

    A Windows job whose runner vanishes needs a human to re-run it (#1669)
    
    A `windows-build` job killed the way #1228 describes fails with no
    failed step, no log and no artifact, so only a re-run clears it. Since
    #1585 that is about one job a fortnight rather than one in eight, so
    this covers the residual, not the old rate.
    
    `tools/windows-kill-grade.sh` decides, and refuses anything ambiguous.
    It collects every job that did not succeed and is not still running. All
    of them must be plain failures, each with no named step and an
    unfinished one, or no steps at all. Test 466 pins that with ten mutants,
    each killed by a case it does not share.
    
    The step re-reads `run_attempt` from the run rather than from the event,
    and allows exactly one re-run. A superseded run is left alone, because
    windows-build cancels in-progress runs of the same ref, so re-running
    the old one would cancel the new one. A push landing between that check
    and the POST still races it.
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit e61d483d412d1bca3513bd5dd12027ef7395e23f
Author: Xavier Roche <roche@httrack.com>
Date:   Fri Sep 11 15:29:43 2026 +0200

    windows-build.yml does not record that the MSYS suite leg was killing the runner (#1667)
    
    The MSYS test-suite leg was killing the hosted runner. Removing it in
    #1585 took the Windows runner-death rate from 12.5% to 0.3% over 1515
    jobs. `windows-build.yml` records only that MSYS wedged, so nothing
    there warns the next person off adding a leg back. The measurement is on
    #1228.
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit 600adfd0d06d4c6cf4732f71f25b82ed62b135eb
Author: Xavier Roche <roche@httrack.com>
Date:   Fri Sep 11 14:05:40 2026 +0200

    Nothing tells a translator to be a native reader, or which files a new language needs (#1665)
    
    Two gaps in `lang/README.md`, both found while answering a forum request
    for a Thai translation.
    
    It never states the rule that matters most. Only a native reader should
    send a translation, and never machine or LLM output, because nobody here
    can check one.
    
    Its "Adding or updating a language" section is written for updating a
    catalog that already exists. Follow it for a new language and the PR
    fails tests 62, 225 and 373. Nothing told the contributor about
    `lang.def`, `lang.indexes`, the two per-catalog pins under `tests/`,
    `install-manifest.txt`, or the credits roster.
    
    So the section is split by role. A translator sends one file, and the
    maintainer steps move under their own heading.
    
    Checked by staging a 31st catalog and running the full suite. That
    turned up two traps, now written down. `lang.indexes` wants the ISO code
    lowercased, and `373_credits.test` needs a `LABEL` row when
    `LANGUAGE_WINDOWSID` is not the English name.
    
    ---------
    
    Signed-off-by: Xavier Roche <xroche@gmail.com>
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

commit b276d1bb83bc21c6bed3ddca8bf59b4f716635c8
Author: Xavier Roche <roche@httrack.com>
Date:   Fri Sep 11 10:48:26 2026 +0200

    hts_set_thread_runner() is exported but no installed header declares it (#1664)
    
    The 3.50-2 release notes tell embedders about three calls, and
    `hts_set_thread_runner()` was not reachable. The symbol is exported, but
    its only declaration sat in `src/htsthread.h`, which no install carries,
    so a caller had to write the prototype by hand.
    
    The declaration now lives in `src/httrack-library.h`, which is
    installed. Installing `htsthread.h` would drag `htswin32.h` in with it,
    and installing `htstools.h` would publish internal link types. The
    `hts_find*` family was already declared in both headers. This drops the
    copy in `htstools.h` and lets that header include the public one. No
    exported symbol is added or removed, so `VERSION_INFO` does not move.
    
    The new test compiles and links a consumer against the installed headers
    alone. Without the change it fails with `error: unknown type name
    'hts_thread_runner'`. `html/library.html` needs no edit, because the
    installed header list is unchanged.
    
    Closes #1663
    
    ---------
    
    Signed-off-by: Xavier Roche <roche@httrack.com>
    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Created: 2026-09-12 Last update: 2026-09-17 19:04
testing migrations
  • This package will soon be part of the auto-openssl transition. You might want to ensure that your package is ready for it. You can probably find supplementary information in the debian-release archives or in the corresponding release.debian.org bug.
news
[rss feed]
  • [2026-09-16] httrack 3.50.2-1 MIGRATED to testing (Debian testing watch)
  • [2026-09-11] Accepted httrack 3.50.2-1 (source) into unstable (Xavier Roche)
  • [2026-09-08] httrack 3.50.1-1 MIGRATED to testing (Debian testing watch)
  • [2026-09-02] Accepted httrack 3.50.1-1 (source) into unstable (Xavier Roche)
  • [2026-09-01] Accepted httrack 3.50.0-2 (source) into unstable (Xavier Roche)
  • [2026-09-01] Accepted httrack 3.50.0-1 (source) into unstable (Xavier Roche)
  • [2026-08-28] Accepted httrack 3.49.25-1 (source) into unstable (Xavier Roche)
  • [2026-08-26] Accepted httrack 3.49.24-1 (source) into unstable (Xavier Roche)
  • [2026-08-26] httrack 3.49.23-1 MIGRATED to testing (Debian testing watch)
  • [2026-08-21] Accepted httrack 3.49.23-1 (source) into unstable (Xavier Roche)
  • [2026-08-21] httrack 3.49.22-1 MIGRATED to testing (Debian testing watch)
  • [2026-08-16] Accepted httrack 3.49.22-1 (source) into unstable (Xavier Roche)
  • [2026-08-13] Accepted httrack 3.49.21-2 (source) into unstable (Xavier Roche)
  • [2026-08-12] Accepted httrack 3.49.21-1 (source) into unstable (Xavier Roche)
  • [2026-08-10] Accepted httrack 3.49.20-1 (source) into unstable (Xavier Roche)
  • [2026-08-08] Accepted httrack 3.49.19-1 (source) into unstable (Xavier Roche)
  • [2026-08-05] Accepted httrack 3.49.18-1 (source) into unstable (Xavier Roche)
  • [2026-08-05] Accepted httrack 3.49.17-1 (source) into unstable (Xavier Roche)
  • [2026-08-04] Accepted httrack 3.49.16-1 (source) into unstable (Xavier Roche)
  • [2026-07-30] Accepted httrack 3.49.15-1 (source) into unstable (Xavier Roche)
  • [2026-07-29] httrack 3.49.14-1 MIGRATED to testing (Debian testing watch)
  • [2026-07-24] Accepted httrack 3.49.14-1 (source) into unstable (Xavier Roche)
  • [2026-07-23] httrack 3.49.13-1 MIGRATED to testing (Debian testing watch)
  • [2026-07-18] Accepted httrack 3.49.13-1 (source) into unstable (Xavier Roche)
  • [2026-07-16] httrack 3.49.12-1 MIGRATED to testing (Debian testing watch)
  • [2026-07-10] Accepted httrack 3.49.12-1 (source) into unstable (Xavier Roche)
  • [2026-07-10] httrack 3.49.11-1 MIGRATED to testing (Debian testing watch)
  • [2026-07-04] Accepted httrack 3.49.11-1 (source) into unstable (Xavier Roche)
  • [2026-07-04] httrack 3.49.10-2 MIGRATED to testing (Debian testing watch)
  • [2026-06-28] Accepted httrack 3.49.10-2 (source) into unstable (Xavier Roche)
  • 1
  • 2
bugs [bug history graph]
  • all: 0
links
  • homepage
  • lintian
  • buildd: logs, reproducibility, cross
  • popcon
  • browse source code
  • other distros
  • security tracker
  • screenshots
ubuntu Ubuntu logo [Information about Ubuntu for Debian Developers]
  • version: 3.50.0-2

Debian Package Tracker — Copyright 2013-2025 The Distro Tracker Developers
Report problems to the tracker.debian.org pseudo-package in the Debian BTS.
Documentation — Bugs — Git Repository — Contributing