Browse Source

Ticket #47456 - delete present values should append values to deleted values

https://fedorahosted.org/389/ticket/47456
Reviewed by: lkrispenz (Thanks!)
Branch: master
Fix Description: When deleting all values, entry_delete_present_values_wsi was
deleting all values in the deleted_values set and replacing them with the
present_values set.  It should not delete the values in the deleted_values
set, it should just add to them.  This also renames valueset_add_valueset
to valueset_set_valueset, which is what it was doing anyway.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
Rich Megginson 12 years ago
parent
commit
50ba5a0906
2 changed files with 27 additions and 10 deletions
  1. 1 1
      ldap/servers/slapd/proto-slap.h
  2. 26 9
      ldap/servers/slapd/valueset.c

+ 1 - 1
ldap/servers/slapd/proto-slap.h

@@ -182,8 +182,8 @@ void valueset_add_valuearray(Slapi_ValueSet *vs, Slapi_Value **addvals);
 void valueset_add_valuearray_ext(Slapi_ValueSet *vs, Slapi_Value **addvals, PRUint32 flags);
 void valueset_add_string(const Slapi_Attr *a, Slapi_ValueSet *vs, const char *s, CSNType t, const CSN *csn);
 void valueset_update_csn(Slapi_ValueSet *vs, CSNType t, const CSN *csn);
-void valueset_add_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2);
 int valueset_intersectswith_valuearray(Slapi_ValueSet *vs, const Slapi_Attr *a, Slapi_Value **values, int *duplicate_index);
+void valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2);
 Slapi_ValueSet *valueset_dup(const Slapi_ValueSet *dupee);
 void valueset_remove_string(const Slapi_Attr *a, Slapi_ValueSet *vs, const char *s);
 int valueset_replace_valuearray(Slapi_Attr *a, Slapi_ValueSet *vs, Slapi_Value **vals);

+ 26 - 9
ldap/servers/slapd/valueset.c

@@ -661,6 +661,9 @@ valueset_set_valuearray_byval(Slapi_ValueSet *vs, Slapi_Value **addvals)
 	PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
 }
 
+/* WARNING: you must call this function with a new vs - if it points to existing data, it
+ * will leak - call slapi_valueset_done to free it first if necessary
+ */
 void
 valueset_set_valuearray_passin(Slapi_ValueSet *vs, Slapi_Value **addvals)
 {
@@ -671,18 +674,21 @@ valueset_set_valuearray_passin(Slapi_ValueSet *vs, Slapi_Value **addvals)
 	PR_ASSERT((vs->sorted == NULL) || (vs->num == 0) || ((vs->sorted[0] >= 0) && (vs->sorted[0] < vs->num)));
 }
 
+/* WARNING: you must call this function with a new vs1 - if it points to existing data, it
+ * will leak - call slapi_valueset_done(vs1) to free it first if necessary
+ */
 void
 slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
 {
 	slapi_valueset_init(vs1);
-	valueset_add_valueset(vs1,vs2);
+	valueset_set_valueset(vs1,vs2);
 }
 
 void
 slapi_valueset_join_attr_valueset(const Slapi_Attr *a, Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
 {
 	if (slapi_valueset_isempty(vs1))
-		valueset_add_valueset(vs1,vs2);
+		valueset_set_valueset(vs1,vs2);
 	else
 		slapi_valueset_add_attr_valuearray_ext (a, vs1, vs2->va, vs2->num, 0, NULL);
 }
@@ -762,7 +768,7 @@ valueset_remove_value_sorted(const Slapi_Attr *a, Slapi_ValueSet *vs, const Slap
 		memmove(&vs->sorted[position],&vs->sorted[position+1],(vs->num - position)*sizeof(int));
 		memmove(&vs->va[index],&vs->va[index+1],(vs->num - index)*sizeof(Slapi_Value *));
 		vs->num--;
-		/* unfortunately the references in the sorted array 
+		/* unfortunately the references in the sorted array
 		 * to values past the removed one are no longer correct
 		 * need to adjust */
 		for (i=0; i < vs->num; i++) {
@@ -1173,13 +1179,14 @@ valueset_add_string(const Slapi_Attr *a, Slapi_ValueSet *vs, const char *s, CSNT
  * The value set is passed in by value.
  */
 void
-valueset_add_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
+valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
 {
 	int i;
 
 	if (vs1 && vs2) {
-		valuearray_free(&vs1->va);
-		slapi_ch_free((void **)&vs1->sorted);
+		int oldmax = vs1->max;
+		/* pre-condition - vs1 empty - otherwise, existing data is overwritten */
+		PR_ASSERT(vs1->num == 0);
 		if (vs2->va) {
 			/* need to copy valuearray */
 			if (vs2->max == 0) {
@@ -1190,16 +1197,26 @@ valueset_add_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
 				vs1->num = vs2->num;
 				vs1->max = vs2->max;
 			}
-			vs1->va = (Slapi_Value **) slapi_ch_malloc( vs1->max * sizeof(Slapi_Value *));
+			/* do we need more room? */
+			if ((NULL == vs1->va) || (oldmax < vs1->max)) {
+				vs1->va = (Slapi_Value **)slapi_ch_realloc((char *)vs1->va, vs1->max * sizeof(Slapi_Value *));
+			}
 			for (i=0; i< vs1->num;i++) {
 				vs1->va[i] = slapi_value_dup(vs2->va[i]);
 			}
 			vs1->va[vs1->num] = NULL;
+		} else {
+			valuearray_free(&vs1->va);
 		}
 		if (vs2->sorted) {
-			vs1->sorted = (int *) slapi_ch_malloc( vs1->max* sizeof(int));
-			memcpy(&vs1->sorted[0],&vs2->sorted[0],vs1->num* sizeof(int));
+			if ((NULL == vs1->sorted) || (oldmax < vs1->max)) {
+				vs1->sorted = (int *)slapi_ch_realloc((char *)vs1->sorted, vs1->max * sizeof(int));
+			}
+			memcpy(&vs1->sorted[0], &vs2->sorted[0], vs1->num * sizeof(int));
+		} else {
+			slapi_ch_free((void **)&vs1->sorted);
 		}
+		/* post-condition */
 		PR_ASSERT((vs1->sorted == NULL) || (vs1->num == 0) || ((vs1->sorted[0] >= 0) && (vs1->sorted[0] < vs1->num)));
 	}
 }