← Commit list

03a792b186

Daniel Stenberg
Daniel Stenberg
2026-04-01
SUCCESS Duration: 422s

Subject

HSTS: cap the list at 1,000 entries

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/hsts.c+15 -1
@@ -91,6 +91,20 @@ void Curl_hsts_cleanup(struct hsts **hp)
}
}
+/* append the new entry to the list after possibly removing an old entry
+ first */
+static void hsts_append(struct hsts *h, struct stsentry *sts)
+{
+ if(Curl_llist_count(&h->list) == MAX_HSTS_ENTRIES) {
+ /* It's full. Remove the first entry in the list */
+ struct Curl_llist_node *e = Curl_llist_head(&h->list);
+ struct stsentry *oldsts = Curl_node_elem(e);
+ Curl_node_remove(e);
+ hsts_free(oldsts);
+ }
+ Curl_llist_append(&h->list, sts, &sts->node);
+}
+
static CURLcode hsts_create(struct hsts *h,
const char *hostname,
size_t hlen,
@@ -111,7 +125,7 @@ static CURLcode hsts_create(struct hsts *h,
memcpy(sts->host, hostname, hlen);
sts->expires = expires;
sts->includeSubDomains = subdomains;
- Curl_llist_append(&h->list, sts, &sts->node);
+ hsts_append(h, sts);
}
return CURLE_OK;
}
lib/hsts.h+2 -0
@@ -28,6 +28,8 @@
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HSTS)
#include "llist.h"
+#define MAX_HSTS_ENTRIES 1000
+
#if defined(DEBUGBUILD) || defined(UNITTESTS)
extern time_t deltatime;
#endif
tests/data/Makefile.am+1 -1
@@ -223,7 +223,7 @@ test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 \
test1658 test1659 test1660 test1661 test1662 test1663 test1664 test1665 \
test1666 test1667 test1668 test1669 \
\
-test1670 test1671 test1672 test1673 \
+test1670 test1671 test1672 test1673 test1674 \
\
test1680 test1681 test1682 test1683 test1684 test1685 \
\
tests/data/test1674+38 -0
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+unittest
+HSTS
+</keywords>
+</info>
+
+<client>
+<features>
+unittest
+HSTS
+</features>
+
+# This date is exactly "20190124 22:34:21" UTC
+<setenv>
+CURL_TIME=1548369261
+</setenv>
+<name>
+HSTS load more than 1,000 entries from file
+</name>
+
+# test 1674 renders the input file itself, then reads it
+<command>
+%LOGDIR/hsts%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<stdout>
+Number of entries: 1000
+</stdout>
+<limits>
+Allocations: 1100
+</limits>
+</verify>
+</testcase>
tests/unit/Makefile.inc+1 -0
@@ -42,6 +42,7 @@ TESTS_C = \
unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c \
unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c \
unit1666.c unit1667.c unit1668.c unit1669.c \
+ unit1674.c \
unit1979.c unit1980.c \
unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c \
unit3200.c unit3205.c \
tests/unit/unit1674.c+82 -0
@@ -0,0 +1,82 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * SPDX-License-Identifier: curl
+ *
+ ***************************************************************************/
+#include "unitcheck.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HSTS)
+
+#include "urldata.h"
+#include "hsts.h"
+
+/* create a HSTS file with lots of unique host names all using the same
+ fixed expire time */
+static void render_unit1674(const char *file)
+{
+ FILE *f = curlx_fopen(file, FOPEN_WRITETEXT);
+ size_t i;
+ if(!f)
+ return;
+ for(i = 0; i < (MAX_HSTS_ENTRIES + 5); i++) {
+ curl_mfprintf(f, "host%zu.readfrom.example \"20211001 04:47:41\"\n", i);
+ }
+ curlx_fclose(f);
+}
+
+static CURLcode test_unit1674(const char *arg)
+{
+ UNITTEST_BEGIN_SIMPLE
+
+ struct hsts *h = Curl_hsts_init();
+ CURL *easy;
+ char savename[256];
+
+ abort_unless(h, "Curl_hsts_init()");
+
+ render_unit1674(arg);
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ easy = curl_easy_init();
+ if(!easy) {
+ Curl_hsts_cleanup(&h);
+ abort_unless(easy, "curl_easy_init()");
+ }
+
+ Curl_hsts_loadfile(easy, h, arg);
+
+ curl_mprintf("Number of entries: %zu\n", Curl_llist_count(&h->list));
+
+ curl_msnprintf(savename, sizeof(savename), "%s.save", arg);
+ (void)Curl_hsts_save(easy, h, savename);
+ Curl_hsts_cleanup(&h);
+ curl_easy_cleanup(easy);
+
+ UNITTEST_END(curl_global_cleanup())
+}
+#else
+static CURLcode test_unit1674(const char *arg)
+{
+ UNITTEST_BEGIN_SIMPLE
+ puts("nothing to do when HTTP or HSTS are disabled");
+ UNITTEST_END_SIMPLE
+}
+#endif