]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
x509/name_constraints: add sorted_view in preparation...
authorAlexander Sosedkin <asosedkin@redhat.com>
Wed, 4 Feb 2026 08:09:46 +0000 (09:09 +0100)
committerAlexander Sosedkin <asosedkin@redhat.com>
Mon, 9 Feb 2026 11:59:26 +0000 (12:59 +0100)
... for actually using it later for performance gains.

Signed-off-by: Alexander Sosedkin <asosedkin@redhat.com>
lib/x509/name_constraints.c

index b5d732d0c58f5091444f936cf6a7c70dad9580f8..41f30d13b9022c2f74b715b2953608588589207f 100644 (file)
@@ -54,6 +54,9 @@ struct name_constraints_node_list_st {
        struct name_constraints_node_st **data;
        size_t size;
        size_t capacity;
+       /* sorted-on-demand view, valid only when dirty == false */
+       bool dirty;
+       struct name_constraints_node_st **sorted_view;
 };
 
 struct gnutls_name_constraints_st {
@@ -342,6 +345,37 @@ static int compare_name_constraint_nodes_qsort(const void *a, const void *b)
        }
 }
 
+/* Bring the sorted view up to date with the list data; clear the dirty flag. */
+static int ensure_sorted(struct name_constraints_node_list_st *list)
+{
+       struct name_constraints_node_st **new_data;
+
+       if (!list->dirty)
+               return GNUTLS_E_SUCCESS;
+       if (!list->size) {
+               list->dirty = false;
+               return GNUTLS_E_SUCCESS;
+       }
+
+       /* reallocate sorted view to match current size */
+       new_data =
+               _gnutls_reallocarray(list->sorted_view, list->size,
+                                    sizeof(struct name_constraints_node_st *));
+       if (!new_data)
+               return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+       list->sorted_view = new_data;
+
+       /* copy pointers and sort in-place */
+       memcpy(list->sorted_view, list->data,
+              list->size * sizeof(struct name_constraints_node_st *));
+       qsort(list->sorted_view, list->size,
+             sizeof(struct name_constraints_node_st *),
+             compare_name_constraint_nodes_qsort);
+
+       list->dirty = false;
+       return GNUTLS_E_SUCCESS;
+}
+
 static int
 name_constraints_node_list_add(struct name_constraints_node_list_st *list,
                               struct name_constraints_node_st *node)
@@ -361,10 +395,23 @@ name_constraints_node_list_add(struct name_constraints_node_list_st *list,
                list->capacity = new_capacity;
                list->data = new_data;
        }
+       list->dirty = true;
        list->data[list->size++] = node;
        return 0;
 }
 
+static void
+name_constraints_node_list_clear(struct name_constraints_node_list_st *list)
+{
+       gnutls_free(list->data);
+       gnutls_free(list->sorted_view);
+       list->data = NULL;
+       list->sorted_view = NULL;
+       list->capacity = 0;
+       list->size = 0;
+       list->dirty = false;
+}
+
 static int
 name_constraints_node_add_new(gnutls_x509_name_constraints_t nc,
                              struct name_constraints_node_list_st *list,
@@ -711,6 +758,7 @@ static int name_constraints_node_list_intersect(
                                permitted->data[i] =
                                        permitted->data[permitted->size - 1];
                        permitted->size--;
+                       permitted->dirty = true;
                        continue;
                }
                i++;
@@ -908,17 +956,9 @@ void _gnutls_x509_name_constraints_clear(gnutls_x509_name_constraints_t nc)
                struct name_constraints_node_st *node = nc->nodes.data[i];
                name_constraints_node_free(node);
        }
-       gnutls_free(nc->nodes.data);
-       nc->nodes.capacity = 0;
-       nc->nodes.size = 0;
-
-       gnutls_free(nc->permitted.data);
-       nc->permitted.capacity = 0;
-       nc->permitted.size = 0;
-
-       gnutls_free(nc->excluded.data);
-       nc->excluded.capacity = 0;
-       nc->excluded.size = 0;
+       name_constraints_node_list_clear(&nc->nodes);
+       name_constraints_node_list_clear(&nc->permitted);
+       name_constraints_node_list_clear(&nc->excluded);
 }
 
 /**