mirror of
https://github.com/xroche/httrack.git
synced 2026-08-15 04:02:04 +03:00
Compare commits
3 Commits
master
...
wizard-fil
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41dfcb8168 | ||
|
|
2d714d073a | ||
|
|
08d469eeb3 |
@@ -698,7 +698,7 @@ int httpmirror(char *url1, httrackp * opt) {
|
||||
}
|
||||
}
|
||||
{
|
||||
htsbuff fb = htsbuff_ptr(filters[filptr], HTS_URLMAXSIZE * 2);
|
||||
htsbuff fb = htsbuff_ptr(filters[filptr], HTS_FILTER_SLOT_SIZE);
|
||||
htsbuff_cpy(&fb, type ? "+" : "-");
|
||||
htsbuff_cat(&fb, tempo);
|
||||
}
|
||||
@@ -2348,7 +2348,7 @@ void host_ban(httrackp * opt, int ptr,
|
||||
// interdire host
|
||||
assertf((*_FILTERS_PTR) < opt->maxfilter);
|
||||
if (*_FILTERS_PTR < opt->maxfilter) {
|
||||
htsbuff fb = htsbuff_ptr(_FILTERS[*_FILTERS_PTR], HTS_URLMAXSIZE * 2);
|
||||
htsbuff fb = htsbuff_ptr(_FILTERS[*_FILTERS_PTR], HTS_FILTER_SLOT_SIZE);
|
||||
htsbuff_cpy(&fb, "-");
|
||||
htsbuff_cat(&fb, host);
|
||||
htsbuff_cat(&fb, "/*"); // forbid host/*
|
||||
@@ -2438,16 +2438,13 @@ int filters_init(char ***ptrfilters, int maxfilter, int filterinc) {
|
||||
}
|
||||
if (filters) {
|
||||
if (filters[0] == NULL) {
|
||||
filters[0] =
|
||||
(char *) malloct(sizeof(char) * (filter_max + 2) *
|
||||
(HTS_URLMAXSIZE * 2));
|
||||
filters[0] = (char *) malloct(sizeof(char) * (filter_max + 2) *
|
||||
HTS_FILTER_SLOT_SIZE);
|
||||
memset(filters[0], 0,
|
||||
sizeof(char) * (filter_max + 2) * (HTS_URLMAXSIZE * 2));
|
||||
sizeof(char) * (filter_max + 2) * HTS_FILTER_SLOT_SIZE);
|
||||
} else {
|
||||
filters[0] =
|
||||
(char *) realloct(filters[0],
|
||||
sizeof(char) * (filter_max +
|
||||
2) * (HTS_URLMAXSIZE * 2));
|
||||
filters[0] = (char *) realloct(
|
||||
filters[0], sizeof(char) * (filter_max + 2) * HTS_FILTER_SLOT_SIZE);
|
||||
}
|
||||
if (filters[0] == NULL) {
|
||||
freet(filters);
|
||||
@@ -2463,7 +2460,7 @@ int filters_init(char ***ptrfilters, int maxfilter, int filterinc) {
|
||||
else
|
||||
from = filter_max - filterinc;
|
||||
for(i = 0; i <= filter_max; i++) { // PLUS UN (sécurité)
|
||||
filters[i] = filters[0] + i * (HTS_URLMAXSIZE * 2);
|
||||
filters[i] = filters[0] + i * HTS_FILTER_SLOT_SIZE;
|
||||
}
|
||||
for(i = from; i <= filter_max; i++) { // PLUS UN (sécurité)
|
||||
filters[i][0] = '\0'; // clear
|
||||
|
||||
@@ -4132,10 +4132,62 @@ static int st_hashkey_bounds(httrackp *opt, int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The pattern answer n owes (adr, fil): a second implementation of the builder,
|
||||
with no bound of its own, to compare it against. */
|
||||
static void wizardfilter_want(htsbuff *w, int n, const char *adr,
|
||||
const char *fil, hts_boolean up) {
|
||||
htsbuff_cpy(w, n <= 2 ? "-" : "+");
|
||||
htsbuff_cat(w, adr);
|
||||
if (n == 2 || n == 6 || (n == 5 && up)) {
|
||||
htsbuff_cat(w, "/*");
|
||||
return;
|
||||
}
|
||||
if (*fil != '/')
|
||||
htsbuff_cat(w, "/");
|
||||
htsbuff_cat(w, fil);
|
||||
if (n == 1 || n == 5)
|
||||
htsbuff_cat(w, "*");
|
||||
else if (n == 7)
|
||||
htsbuff_cat(w, HTS_WIZARD_FILTER_SUFFIX);
|
||||
}
|
||||
|
||||
/* A link of the given lengths: adr all 'a', fil a directory of 'b' ending on a
|
||||
slash for answers 1, 5 and 7 to anchor on, led by one when `slash`. */
|
||||
static void wizardfilter_link(char *adr, size_t adrlen, char *fil,
|
||||
size_t fillen, hts_boolean slash) {
|
||||
memset(adr, 'a', adrlen);
|
||||
adr[adrlen] = '\0';
|
||||
memset(fil, 'b', fillen);
|
||||
fil[0] = slash ? '/' : 'b';
|
||||
fil[fillen - 1] = '/';
|
||||
fil[fillen] = '\0';
|
||||
}
|
||||
|
||||
/* Asserts every answer that emits a filter for (adr, fil) emits exactly what
|
||||
wizardfilter_want() owes, and returns the longest pattern seen. */
|
||||
static size_t wizardfilter_emits(htsbuff *f, char *expect, const char *adr,
|
||||
const char *fil) {
|
||||
static const int answers[] = {0, 1, 2, 5, 6, 7};
|
||||
size_t i, up, longest = 0;
|
||||
|
||||
for (i = 0; i < sizeof(answers) / sizeof(answers[0]); i++) {
|
||||
for (up = 0; up < 2; up++) {
|
||||
const hts_boolean seek = up != 0 ? HTS_TRUE : HTS_FALSE;
|
||||
htsbuff w = htsbuff_ptr(expect, HTS_FILTER_SLOT_SIZE);
|
||||
|
||||
wizardfilter_want(&w, answers[i], adr, fil, seek);
|
||||
hts_wizard_answer_filter(f, 0, answers[i], adr, fil, seek);
|
||||
assertf(strcmp(f->buf, expect) == 0);
|
||||
longest = f->len > longest ? f->len : longest;
|
||||
}
|
||||
}
|
||||
return longest;
|
||||
}
|
||||
|
||||
/* Prints the filter answer <n> emits for (adr, fil) [up] in [slot]; with no
|
||||
arguments, asserts every answer against its expected pattern (#1119). */
|
||||
static int st_wizardfilter(httrackp *opt, int argc, char **argv) {
|
||||
char pattern[HTS_URLMAXSIZE * 2];
|
||||
char pattern[HTS_FILTER_SLOT_SIZE];
|
||||
htsbuff f = htsbuff_array(pattern);
|
||||
|
||||
(void) opt;
|
||||
@@ -4188,6 +4240,33 @@ static int st_wizardfilter(httrackp *opt, int argc, char **argv) {
|
||||
EMITS(5, "foo.com", "page.html", HTS_FALSE, "");
|
||||
EMITS(7, "foo.com", "page.html", HTS_FALSE, "");
|
||||
|
||||
/* A long link must emit the same pattern a short one does, byte for byte:
|
||||
clipping it would widen the rule (a cut "*[file]" becomes "*"), and the
|
||||
lengths come from the wire. Sweeps the old 2048-byte slot, then the real
|
||||
worst case, both link buffers full. */
|
||||
{
|
||||
const size_t urlmax = HTS_URLMAXSIZE * 2 - 1; /* the engine's adr and fil */
|
||||
char *adr = malloct(urlmax + 1);
|
||||
char *fil = malloct(urlmax + 1);
|
||||
char *expect = malloct(HTS_FILTER_SLOT_SIZE);
|
||||
size_t total;
|
||||
|
||||
for (total = 2040; total <= 2048; total++) {
|
||||
const size_t adrlen = total / 2, fillen = total - 1 - adrlen;
|
||||
|
||||
wizardfilter_link(adr, adrlen, fil, fillen, HTS_TRUE);
|
||||
wizardfilter_emits(&f, expect, adr, fil);
|
||||
}
|
||||
/* the real maximum: both buffers full, and no leading slash on fil to
|
||||
spare the separator. It fills the slot exactly, NUL included */
|
||||
wizardfilter_link(adr, urlmax, fil, urlmax, HTS_FALSE);
|
||||
assertf(wizardfilter_emits(&f, expect, adr, fil) ==
|
||||
HTS_FILTER_SLOT_SIZE - 1);
|
||||
freet(adr);
|
||||
freet(fil);
|
||||
freet(expect);
|
||||
}
|
||||
|
||||
/* the answers that add no filter at all */
|
||||
EMITS(-1, "foo.com", "/x", HTS_FALSE, "");
|
||||
EMITS(3, "foo.com", "/x", HTS_FALSE, "");
|
||||
|
||||
@@ -43,10 +43,6 @@ Please visit our Website: http://www.httrack.com
|
||||
/* END specific definitions */
|
||||
|
||||
// libérer filters[0] pour insérer un élément dans filters[0]
|
||||
/* Per-slot capacity of the filters array, matching the slot stride allocated by
|
||||
filters_init() in htscore.c (HTS_URLMAXSIZE * 2). */
|
||||
#define HTS_FILTER_SLOT_SIZE (HTS_URLMAXSIZE * 2)
|
||||
|
||||
#define HT_INSERT_FILTERS0 \
|
||||
do { \
|
||||
int i; \
|
||||
@@ -265,6 +261,8 @@ void hts_wizard_answer_filter(htsbuff *f, int slot, int n, const char *adr,
|
||||
while (fil[dir] != '/' && dir > 0)
|
||||
dir--;
|
||||
|
||||
/* a clipped pattern would be a wider rule than the answer asked for */
|
||||
assertf(f->cap >= HTS_FILTER_SLOT_SIZE);
|
||||
htsbuff_cpy(f, "");
|
||||
if (hts_wizard_scope_answer(n) != HTS_DEFAULT) {
|
||||
wizard_cat_scope(f, hts_wizard_scope_answer(n) == HTS_TRUE ? "-" : "+", adr,
|
||||
@@ -313,7 +311,7 @@ void hts_wizard_answer_filter(htsbuff *f, int slot, int n, const char *adr,
|
||||
case 7: /* this directory, files only */
|
||||
if (fil[dir] == '/') {
|
||||
wizard_cat_path(f, "+", adr, fil, dir + 1);
|
||||
htsbuff_cat(f, "*[file]");
|
||||
htsbuff_cat(f, HTS_WIZARD_FILTER_SUFFIX);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -61,10 +61,22 @@ hts_boolean hts_robots_forbids(httrackp *opt, const char *adr, const char *fil,
|
||||
caller stops at the first empty one. */
|
||||
#define HTS_WIZARD_MAX_FILTERS 2
|
||||
|
||||
/* The longest suffix an answer appends after the link (answer 7). */
|
||||
#define HTS_WIZARD_FILTER_SUFFIX "*[file]"
|
||||
|
||||
/* Capacity of one filters[] slot, and the stride filters_init() allocates in
|
||||
htscore.c: change the two together. Sized for the longest pattern an answer
|
||||
can build (sign, host, separator, path, suffix), because clipping one widens
|
||||
it: "*[file]" cut back to "*" allows every file below, not just this one. */
|
||||
#define HTS_FILTER_SLOT_SIZE \
|
||||
(1 + (HTS_URLMAXSIZE * 2 - 1) + 1 + (HTS_URLMAXSIZE * 2 - 1) + \
|
||||
sizeof(HTS_WIZARD_FILTER_SUFFIX))
|
||||
|
||||
/* Builds into `f` the `slot`-th filter answer `n` adds for the link (adr,fil),
|
||||
and leaves `f` empty past the last one. Only the host-scope answers emit a
|
||||
second, because their starred form misses the apex. `seeker_up` is the
|
||||
HTS_SEEKER_UP bit of opt->seeker, read by answer 5. */
|
||||
HTS_SEEKER_UP bit of opt->seeker, read by answer 5. `f` must have a full
|
||||
HTS_FILTER_SLOT_SIZE of capacity, so no pattern is ever truncated. */
|
||||
void hts_wizard_answer_filter(htsbuff *f, int slot, int n, const char *adr,
|
||||
const char *fil, hts_boolean seeker_up);
|
||||
|
||||
|
||||
30
tests/300_engine-wizard-filter-size.test
Executable file
30
tests/300_engine-wizard-filter-size.test
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source=tests/testlib.sh
|
||||
. "$(dirname "$0")/testlib.sh"
|
||||
|
||||
# #1264/#1266: the pattern is cut from the link the question is about, so a long
|
||||
# enough one used to outgrow the filter slot. It must neither abort the run nor
|
||||
# clip: a clipped pattern is a wider rule than the one the answer asked for.
|
||||
|
||||
# each CLI argument stays under HTS_CDLMAXSIZE, so the length comes from both
|
||||
adr=$(printf 'a%.0s' $(seq 1 1023))
|
||||
|
||||
# 1 + len(adr) + len(fil), sweeping the 2048 bytes the slot used to hold
|
||||
for total in $(seq 2040 2047); do
|
||||
fil=/$(printf 'b%.0s' $(seq 1 $((total - ${#adr} - 3))))/
|
||||
test $((1 + ${#adr} + ${#fil})) -eq "$total" || fail "bad length for $total"
|
||||
assert_selftest "-$adr$fil" wizardfilter 0 "$adr" "$fil"
|
||||
assert_selftest "-$adr$fil*" wizardfilter 1 "$adr" "$fil"
|
||||
assert_selftest "-$adr/*" wizardfilter 2 "$adr" "$fil"
|
||||
assert_selftest "+$adr$fil*" wizardfilter 5 "$adr" "$fil"
|
||||
assert_selftest "+$adr/*" wizardfilter 6 "$adr" "$fil"
|
||||
assert_selftest "+$adr$fil*[file]" wizardfilter 7 "$adr" "$fil"
|
||||
done
|
||||
|
||||
# a command line cannot express the rest of the sweep, up to both link buffers
|
||||
# full; the self-test carries it
|
||||
assert_selftest "wizardfilter self-test OK" wizardfilter
|
||||
Reference in New Issue
Block a user