|
|
dc8c34 |
From c6ffb6173c57228a48f97e935b7f6436a3897063 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Noriko Hosoi <nhosoi@redhat.com>
|
|
|
dc8c34 |
Date: Mon, 24 Feb 2014 16:42:36 -0800
|
|
|
dc8c34 |
Subject: [PATCH 170/225] Ticket #47455 - valgrind - value mem leaks, uninit
|
|
|
dc8c34 |
mem usage
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Backported the valueset.c part of commit 3adc242bcc8c6d0d05d5d9773f32b4f81afb6e6d.
|
|
|
dc8c34 |
Author: Rich Megginson <rmeggins@redhat.com>
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47455
|
|
|
dc8c34 |
Fix Description: The problem was that slapi_valueset_add_attr_valuearray_ext
|
|
|
dc8c34 |
was assuming the caller was going to free the entire given vs upon failure.
|
|
|
dc8c34 |
This is fine for the value replace case but not for the add 1 value case.
|
|
|
dc8c34 |
Callers of slapi_valueset_add_attr_valuearray_ext must provide
|
|
|
dc8c34 |
the dup_index parameter if using SLAPI_VALUE_FLAG_PASSIN and
|
|
|
dc8c34 |
SLAPI_VALUE_FLAG_DUPCHECK, and if there is more than one value. The caller
|
|
|
dc8c34 |
needs to know which of the values from addvals is in vs to properly clean up
|
|
|
dc8c34 |
with no memory leaks.
|
|
|
dc8c34 |
Platforms tested: RHEL6 x86_64
|
|
|
dc8c34 |
Flag Day: no
|
|
|
dc8c34 |
Doc impact: no
|
|
|
dc8c34 |
(cherry picked from commit 3adc242bcc8c6d0d05d5d9773f32b4f81afb6e6d)
|
|
|
dc8c34 |
(cherry picked from commit 6357ced2e4380def053966e849eac45e44009662)
|
|
|
dc8c34 |
(cherry picked from commit 8252d02654cc616beb4558421cd292d470b150cf)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/valueset.c | 55 +++++++++++++++++++++++++++++++------------
|
|
|
dc8c34 |
1 file changed, 40 insertions(+), 15 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
|
|
|
dc8c34 |
index 4ee2938..29078d4 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/valueset.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/valueset.c
|
|
|
dc8c34 |
@@ -1014,6 +1014,15 @@ valueset_insert_value_to_sorted(const Slapi_Attr *a, Slapi_ValueSet *vs, Slapi_V
|
|
|
dc8c34 |
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+/*
|
|
|
dc8c34 |
+ * If this function returns an error, it is safe to do both
|
|
|
dc8c34 |
+ * slapi_valueset_done(vs);
|
|
|
dc8c34 |
+ * and
|
|
|
dc8c34 |
+ * valuearray_free(&addvals);
|
|
|
dc8c34 |
+ * if there is an error and the PASSIN flag is used, the addvals array will own all of the values
|
|
|
dc8c34 |
+ * vs will own none of the values - so you should do both slapi_valueset_done(vs) and valuearray_free(&add
|
|
|
dc8c34 |
+ * to clean up
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
int
|
|
|
dc8c34 |
slapi_valueset_add_attr_valuearray_ext(const Slapi_Attr *a, Slapi_ValueSet *vs,
|
|
|
dc8c34 |
Slapi_Value **addvals, int naddvals, unsigned long flags, int *dup_index)
|
|
|
dc8c34 |
@@ -1086,8 +1095,13 @@ slapi_valueset_add_attr_valuearray_ext(const Slapi_Attr *a, Slapi_ValueSet *vs,
|
|
|
dc8c34 |
if (dup < 0 ) {
|
|
|
dc8c34 |
rc = LDAP_TYPE_OR_VALUE_EXISTS;
|
|
|
dc8c34 |
if (dup_index) *dup_index = i;
|
|
|
dc8c34 |
- if ( !passin)
|
|
|
dc8c34 |
+ if (passin) {
|
|
|
dc8c34 |
+ PR_ASSERT((i == 0) || dup_index);
|
|
|
dc8c34 |
+ /* caller must provide dup_index to know how far we got in addvals */
|
|
|
dc8c34 |
+ (vs->va)[vs->num] = NULL;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
slapi_value_free(&(vs->va)[vs->num]);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
break;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
@@ -1310,31 +1324,42 @@ valueset_replace_valuearray_ext(Slapi_Attr *a, Slapi_ValueSet *vs, Slapi_Value *
|
|
|
dc8c34 |
vs->max = vals_count + 1;
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
/* verify the given values are not duplicated. */
|
|
|
dc8c34 |
+ unsigned long flags = SLAPI_VALUE_FLAG_PASSIN|SLAPI_VALUE_FLAG_DUPCHECK;
|
|
|
dc8c34 |
+ int dupindex = 0;
|
|
|
dc8c34 |
Slapi_ValueSet *vs_new = slapi_valueset_new();
|
|
|
dc8c34 |
- rc = slapi_valueset_add_attr_valuearray_ext (a, vs_new, valstoreplace, vals_count, 0, NULL);
|
|
|
dc8c34 |
+ rc = slapi_valueset_add_attr_valuearray_ext (a, vs_new, valstoreplace, vals_count, flags, &dupindex);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ( rc == LDAP_SUCCESS )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
+ /* used passin, so vs_new owns all of the Slapi_Value* in valstoreplace
|
|
|
dc8c34 |
+ * so tell valuearray_free_ext to start at index vals_count, which is
|
|
|
dc8c34 |
+ * NULL, then just free valstoreplace
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ valuearray_free_ext(&valstoreplace, vals_count);
|
|
|
dc8c34 |
/* values look good - replace the values in the attribute */
|
|
|
dc8c34 |
- if(!valuearray_isempty(vs->va))
|
|
|
dc8c34 |
- {
|
|
|
dc8c34 |
- /* remove old values */
|
|
|
dc8c34 |
- slapi_valueset_done(vs);
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
- vs->va = vs_new->va;
|
|
|
dc8c34 |
+ if(!valuearray_isempty(vs->va))
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
+ /* remove old values */
|
|
|
dc8c34 |
+ slapi_valueset_done(vs);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ vs->va = vs_new->va;
|
|
|
dc8c34 |
vs_new->va = NULL;
|
|
|
dc8c34 |
- vs->sorted = vs_new->sorted;
|
|
|
dc8c34 |
+ vs->sorted = vs_new->sorted;
|
|
|
dc8c34 |
vs_new->sorted = NULL;
|
|
|
dc8c34 |
- vs->num = vs_new->num;
|
|
|
dc8c34 |
- vs->max = vs_new->max;
|
|
|
dc8c34 |
+ vs->num = vs_new->num;
|
|
|
dc8c34 |
+ vs->max = vs_new->max;
|
|
|
dc8c34 |
slapi_valueset_free (vs_new);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
else
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- /* caller expects us to own valstoreplace - since we cannot
|
|
|
dc8c34 |
- use them, just delete them */
|
|
|
dc8c34 |
- slapi_valueset_free(vs_new);
|
|
|
dc8c34 |
- valuearray_free(&valstoreplace);
|
|
|
dc8c34 |
+ /* caller expects us to own valstoreplace - since we cannot
|
|
|
dc8c34 |
+ use them, just delete them */
|
|
|
dc8c34 |
+ /* using PASSIN, some of the Slapi_Value* are in vs_new, and the rest
|
|
|
dc8c34 |
+ * after dupindex are in valstoreplace
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ slapi_valueset_free(vs_new);
|
|
|
dc8c34 |
+ valuearray_free_ext(&valstoreplace, dupindex);
|
|
|
dc8c34 |
+ PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
return rc;
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.8.1.4
|
|
|
dc8c34 |
|