sblim-sfcb/sblim-sfcb-1.3.16-embedded-...

104 lines
3.8 KiB
Diff

replaceClStringN() relocates items in ClStrBuf, using strlen() to get
lengths of the items. With embedded instances / objects, strlen() is not
useful at all, we must get length of the item using other means.
The patch is quite crude, there might be better way, how to get the lenghts
(e.g. by having ClStrBuf.lenPtr[], which would track lenght of each item).
Version 2: do not get lengths from fb->indexPtr, it is being modified,
use a copy of it instead.
diff -up sblim-sfcb-1.3.16/objectImpl.c.embedded-crash sblim-sfcb-1.3.16/objectImpl.c
--- sblim-sfcb-1.3.16/objectImpl.c.embedded-crash 2013-04-18 16:49:51.941521957 +0200
+++ sblim-sfcb-1.3.16/objectImpl.c 2013-04-18 16:39:30.000000000 +0200
@@ -449,6 +449,29 @@ static void replaceClString(ClObjectHdr
return replaceClStringN(hdr, id, str, 0);
}
+static int getBufIndexLen(int *indexPtr, int bUsed, int iUsed, int index)
+{
+ /*
+ * Find length of 'string' in fb at given index.
+ * We cannot use strlen, because some items are not strings but embedded
+ * instances.
+ * We cannot simply substract fb->indexPtr[index+1] - fb->indexPtr[index],
+ * because the entries are not consecutive! They are shuffled by
+ * replaceClStringN().
+ * Therefore the only way to find a length of our 'string' is to find
+ * string, which starts immediately after it. Let's call it 'nearest'
+ * string. */
+ int nearest_start = bUsed;
+ int our_start = indexPtr[index];
+ int i;
+ for (i = 0; i<iUsed; i++)
+ if (indexPtr[i] > our_start && indexPtr[i] < nearest_start) {
+ nearest_start = indexPtr[i];
+ }
+ int len = nearest_start - our_start;
+ return len;
+}
+
static void
replaceClStringN(ClObjectHdr * hdr, int id, const char *str, unsigned int length)
{
@@ -457,15 +480,20 @@ replaceClStringN(ClObjectHdr * hdr, int
char *ts, *fs;
long i, l, u;
ClStrBuf *fb;
+ int *oldIndexPtr;
fb = getStrBufPtr(hdr);
ts = (char *) malloc(fb->bUsed);
fs = &fb->buf[0];
+ /* Copy indexPtr from the buffer, so we can compute lengths of items in it.*/
+ oldIndexPtr = (int*) malloc(sizeof(int)*fb->iUsed);
+ memcpy(oldIndexPtr, fb->indexPtr, sizeof(int)*fb->iUsed);
+
for (u = i = 0; i < fb->iUsed; i++) {
if (i != id - 1) {
char *f = fs + fb->indexPtr[i];
- l = strlen(f) + 1;
+ l = getBufIndexLen(oldIndexPtr, fb->bUsed, fb->iUsed, i);
fb->indexPtr[i] = u;
memcpy(ts + u, f, l);
u += l;
@@ -474,6 +502,7 @@ replaceClStringN(ClObjectHdr * hdr, int
memcpy(fs, ts, u);
fb->bUsed = u;
free(ts);
+ free(oldIndexPtr);
i = addClStringN(hdr, str, length);
fb = getStrBufPtr(hdr);
@@ -498,16 +527,20 @@ removeClObject(ClObjectHdr * hdr, int id
// char *tmpstr = NULL;
long i, l, u;
ClStrBuf *fb;
+ int *oldIndexPtr;
fb = getStrBufPtr(hdr);
ts = (char *) malloc(fb->bUsed); /* tmp string buffer */
fs = &fb->buf[0];
+ /* Copy indexPtr from the buffer, so we can compute lengths of items in it.*/
+ oldIndexPtr = (int*) malloc(sizeof(int)*fb->iUsed);
+ memcpy(oldIndexPtr, fb->indexPtr, sizeof(int)*fb->iUsed);
for (u = i = 0; i < fb->iUsed; i++) {
if (i != id - 1) { /* loop through and copy over all _other_ properties */
// fprintf(stderr, "replace: keeping %ld\n", i);
char *f = fs + fb->indexPtr[i];
- l = fb->indexPtr[i+1] - fb->indexPtr[i];
+ l = getBufIndexLen(oldIndexPtr, fb->bUsed, fb->iUsed, i);
/* Bugzilla 74159 - Align the string buffer & null terminate */
/*if (l % sizeof(long) != 0) {
@@ -535,6 +568,7 @@ removeClObject(ClObjectHdr * hdr, int id
memcpy(fs, ts, u);
fb->bUsed = u;
free(ts);
+ free(oldIndexPtr);
fb->iUsed--; /* fixup the item count, since we have one fewer elements */