Skip to content

Commit 210f48d

Browse files
committed
Added proper size check before copying the data, minor fixes and improvements.
1 parent 4bb4e58 commit 210f48d

File tree

1 file changed

+151
-7
lines changed

1 file changed

+151
-7
lines changed

src/shared_ispell.c

Lines changed: 151 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,13 @@ typedef struct DictInfo {
8484
static SegmentInfo * segment_info = NULL;
8585

8686
static char * shalloc(int bytes);
87+
8788
static SharedIspellDict * copyIspellDict(IspellDict * dict, char * dictFile, char * affixFile);
8889
static SharedStopList * copyStopList(StopList * list, char * stopFile);
8990

91+
static int sizeIspellDict(IspellDict * dict, char * dictFile, char * affixFile);
92+
static int sizeStopList(StopList * list, char * stopFile);
93+
9094
/*
9195
* Module load callback
9296
*/
@@ -219,6 +223,8 @@ SharedStopList * get_shared_stop_list(char * stop) {
219223
static
220224
void init_shared_dict(DictInfo * info, char * dictFile, char * affFile, char * stopFile) {
221225

226+
int size;
227+
222228
SharedIspellDict * shdict;
223229
SharedStopList * shstop;
224230

@@ -249,23 +255,43 @@ void init_shared_dict(DictInfo * info, char * dictFile, char * affFile, char * s
249255
NISortAffixes(dict);
250256

251257
NIFinishBuild(dict);
252-
258+
259+
/* check available space in shared segment */
260+
size = sizeIspellDict(dict, dictFile, affFile);
261+
if (size > segment_info->available) {
262+
elog(ERROR, "shared dictionary %s.dict / %s.affix needs %d B, only %ld B available",
263+
dictFile, affFile, size, segment_info->available);
264+
}
265+
266+
/* fine, there's enough space - copy the dictionary */
253267
shdict = copyIspellDict(dict, dictFile, affFile);
254268

269+
elog(INFO, "shared dictionary %s.dict / %s.affix loaded, used %d B, %ld B remaining",
270+
dictFile, affFile, size, segment_info->available);
271+
255272
shdict->next = segment_info->dict;
256273
segment_info->dict = shdict;
257274

258-
elog(LOG, "shared ispell init done, remaining %ld B", segment_info->available);
259-
260275
}
261276

262277
/* stop words */
263278
shstop = get_shared_stop_list(stopFile);
264279
if ((shstop == NULL) && (stopFile != NULL)) {
265280

266281
readstoplist(stopFile, &stoplist, lowerstr);
282+
283+
size = sizeStopList(&stoplist, stopFile);
284+
if (size > segment_info->available) {
285+
elog(ERROR, "shared stoplist %s.stop needs %d B, only %ld B available",
286+
stopFile, size, segment_info->available);
287+
}
288+
289+
/* fine, there's enough space - copy the stoplist */
267290
shstop = copyStopList(&stoplist, stopFile);
268291

292+
elog(INFO, "shared stoplist %s.stop loaded, used %d B, %ld B remaining",
293+
affFile, size, segment_info->available);
294+
269295
shstop->next = segment_info->stop;
270296
segment_info->stop = shstop;
271297

@@ -517,6 +543,25 @@ SPNode * copySPNode(SPNode * node) {
517543
return copy;
518544
}
519545

546+
static
547+
int sizeSPNode(SPNode * node) {
548+
549+
int i;
550+
int size = 0;
551+
552+
if (node == NULL) {
553+
return 0;
554+
}
555+
556+
size = MAXALIGN(offsetof(SPNode,data) + sizeof(SPNodeData) * node->length);
557+
558+
for (i = 0; i < node->length; i++) {
559+
size += sizeSPNode(node->data[i].node);
560+
}
561+
562+
return size;
563+
}
564+
520565
static
521566
char * shstrcpy(char * str) {
522567
char * tmp = shalloc(strlen(str)+1);
@@ -538,6 +583,18 @@ RegisNode * copyRegisNode(RegisNode * node) {
538583
return copy;
539584
}
540585

586+
static
587+
int sizeRegisNode(RegisNode * node) {
588+
589+
int size = MAXALIGN(offsetof(RegisNode, data) + node->len);
590+
591+
if (node->next != NULL) {
592+
size += sizeRegisNode(node->next);
593+
}
594+
595+
return size;
596+
}
597+
541598
static
542599
AFFIX * copyAffix(AFFIX * affix) {
543600

@@ -559,6 +616,25 @@ AFFIX * copyAffix(AFFIX * affix) {
559616

560617
}
561618

619+
static
620+
int sizeAffix(AFFIX * affix) {
621+
622+
int size = MAXALIGN(sizeof(AFFIX));
623+
624+
size += MAXALIGN(strlen(affix->find)+1);
625+
size += MAXALIGN(strlen(affix->repl)+1);
626+
627+
if (affix->isregis) {
628+
size += sizeRegisNode(affix->reg.regis.node);
629+
} else if (! affix->issimple) {
630+
// FIXME handle the regex_t properly (copy the strings etc)
631+
elog(WARNING, "skipping regex_t");
632+
}
633+
634+
return size;
635+
636+
}
637+
562638
static
563639
AffixNode * copyAffixNode(AffixNode * node) {
564640

@@ -570,7 +646,7 @@ AffixNode * copyAffixNode(AffixNode * node) {
570646
}
571647

572648
copy = (AffixNode *)shalloc(offsetof(AffixNode,data) + sizeof(AffixNodeData) * node->length);
573-
memcpy(copy, node, offsetof(SPNode,data) + sizeof(SPNodeData) * node->length);
649+
memcpy(copy, node, offsetof(AffixNode,data) + sizeof(AffixNodeData) * node->length);
574650

575651
for (i = 0; i < node->length; i++) {
576652

@@ -579,7 +655,6 @@ AffixNode * copyAffixNode(AffixNode * node) {
579655
copy->data[i].val = node->data[i].val;
580656
copy->data[i].naff = node->data[i].naff;
581657
copy->data[i].aff = (AFFIX**)shalloc(sizeof(AFFIX*) * node->data[i].naff);
582-
memset(copy->data[i].aff, 0, sizeof(AFFIX*) * node->data[i].naff);
583658

584659
for (j = 0; j < node->data[i].naff; j++) {
585660
copy->data[i].aff[j] = copyAffix(node->data[i].aff[j]);
@@ -589,6 +664,31 @@ AffixNode * copyAffixNode(AffixNode * node) {
589664
return copy;
590665
}
591666

667+
static
668+
int sizeAffixNode(AffixNode * node) {
669+
670+
int i, j;
671+
int size = 0;
672+
673+
if (node == NULL) {
674+
return 0;
675+
}
676+
677+
size = MAXALIGN(offsetof(AffixNode,data) + sizeof(AffixNodeData) * node->length);
678+
679+
for (i = 0; i < node->length; i++) {
680+
681+
size += sizeAffixNode(node->data[i].node);
682+
size += MAXALIGN(sizeof(AFFIX*) * node->data[i].naff);
683+
684+
for (j = 0; j < node->data[i].naff; j++) {
685+
size += sizeAffix(node->data[i].aff[j]);
686+
}
687+
}
688+
689+
return size;
690+
}
691+
592692
static
593693
SharedStopList * copyStopList(StopList * list, char * stopFile) {
594694

@@ -608,6 +708,22 @@ SharedStopList * copyStopList(StopList * list, char * stopFile) {
608708
return copy;
609709
}
610710

711+
static
712+
int sizeStopList(StopList * list, char * stopFile) {
713+
714+
int i;
715+
int size = MAXALIGN(sizeof(SharedStopList));
716+
717+
size += MAXALIGN(sizeof(char*) * list->len);
718+
size += MAXALIGN(strlen(stopFile) + 1);
719+
720+
for (i = 0; i < list->len; i++) {
721+
size += MAXALIGN(strlen(list->stop[i]) + 1);
722+
}
723+
724+
return size;
725+
}
726+
611727
static
612728
int countCMPDAffixes(CMPDAffix * affixes) {
613729

@@ -652,8 +768,7 @@ SharedIspellDict * copyIspellDict(IspellDict * dict, char * dictFile, char * aff
652768
copy->nAffixData = dict->nAffixData;
653769
copy->AffixData = (char**)shalloc(sizeof(char*) * dict->nAffixData);
654770
for (i = 0; i < copy->nAffixData; i++) {
655-
copy->AffixData[i] = (char*)shalloc(sizeof(char) * strlen(dict->AffixData[i]) + 1);
656-
strcpy(copy->AffixData[i], dict->AffixData[i]);
771+
copy->AffixData[i] = shstrcpy(dict->AffixData[i]);
657772
}
658773

659774
/* copy compound affixes (there's at least one) */
@@ -667,3 +782,32 @@ SharedIspellDict * copyIspellDict(IspellDict * dict, char * dictFile, char * aff
667782
return copy;
668783

669784
}
785+
786+
static
787+
int sizeIspellDict(IspellDict * dict, char * dictFile, char * affixFile) {
788+
789+
int i;
790+
int size = MAXALIGN(sizeof(SharedIspellDict));
791+
792+
size += MAXALIGN(strlen(dictFile)+1);
793+
size += MAXALIGN(strlen(affixFile)+1);
794+
795+
size += MAXALIGN(sizeof(AFFIX) * dict->naffixes);
796+
797+
size += MAXALIGN(sizeAffixNode(dict->Suffix));
798+
size += MAXALIGN(sizeAffixNode(dict->Prefix));
799+
800+
size += sizeSPNode(dict->Dictionary);
801+
802+
/* copy affix data */
803+
size += MAXALIGN(sizeof(char*) * dict->nAffixData);
804+
for (i = 0; i < dict->nAffixData; i++) {
805+
size += MAXALIGN(sizeof(char) * strlen(dict->AffixData[i]) + 1);
806+
}
807+
808+
/* copy compound affixes (there's at least one) */
809+
size += MAXALIGN(sizeof(CMPDAffix) * countCMPDAffixes(dict->CompoundAffix));
810+
811+
return size;
812+
813+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy