Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbdcadfe

Browse files
author
Arthur Zakirov
committed
Teodor Sigaev
Fix segmentation fault. init_shared_dict() copied dictFile intoinfo->affixFile and info->stopFile.
1 parent62df307 commitbdcadfe

File tree

4 files changed

+77
-38
lines changed

4 files changed

+77
-38
lines changed

‎expected/shared_ispell.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,9 @@ SELECT ts_lexize('shared_hunspell', 'skies');
211211
{sky}
212212
(1 row)
213213

214+
SELECT ts_lexize('shared_hunspell', 'skies');
215+
ts_lexize
216+
-----------
217+
{sky}
218+
(1 row)
219+

‎sql/shared_ispell.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ SELECT stop_name, words FROM shared_ispell_stoplists();
5353
SELECT shared_ispell_reset();
5454

5555
SELECT ts_lexize('shared_ispell','skies');
56-
SELECT ts_lexize('shared_hunspell','skies');
56+
SELECT ts_lexize('shared_hunspell','skies');
57+
SELECT ts_lexize('shared_hunspell','skies');

‎src/shared_ispell.c

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,33 @@
2020
* ===== shared segment init (postmaster startup) =====
2121
*
2222
* _PG_init
23-
* -> ispell_shmem_startup (registered as a hook)
23+
* -> ispell_shmem_startup (registered as a hook)
2424
*
2525
* ===== dictionary init (backend) =====
2626
*
2727
* dispell_init
28-
* -> init_shared_dict
29-
* -> get_shared_dict
30-
* -> NIStartBuild
31-
* -> NIImportDictionary
32-
* -> NIImportAffixes
33-
* -> NISortDictionary
34-
* -> NISortAffixes
35-
* -> NIFinishBuild
36-
* -> sizeIspellDict
37-
* -> copyIspellDict
38-
* -> copySPNode
39-
* -> get_shared_stop_list
40-
* -> readstoplist
41-
* -> copyStopList
28+
* -> init_shared_dict
29+
* -> get_shared_dict
30+
* -> NIStartBuild
31+
* -> NIImportDictionary
32+
* -> NIImportAffixes
33+
* -> NISortDictionary
34+
* -> NISortAffixes
35+
* -> NIFinishBuild
36+
* -> sizeIspellDict
37+
* -> copyIspellDict
38+
* -> copySPNode
39+
* -> get_shared_stop_list
40+
* -> readstoplist
41+
* -> copyStopList
4242
*
4343
* ===== dictionary reinit after reset (backend) =====
4444
*
4545
* dispell_lexize
46-
* -> timestamp of lookup < last reset
47-
* -> init_shared_dict
48-
* (see dispell_init above)
49-
* -> SharedNINormalizeWord
46+
* -> timestamp of lookup < last reset
47+
* -> init_shared_dict
48+
* (see dispell_init above)
49+
* -> SharedNINormalizeWord
5050
*/
5151

5252
#include"postgres.h"
@@ -166,7 +166,7 @@ _PG_fini(void)
166166
staticvoid
167167
ispell_shmem_startup()
168168
{
169-
boolfound=false;
169+
boolfound=FALSE;
170170
char*segment;
171171

172172
if (prev_shmem_startup_hook)
@@ -185,6 +185,12 @@ ispell_shmem_startup()
185185
/* Was the shared memory segment already initialized? */
186186
if (!found)
187187
{
188+
if (segment==NULL) {
189+
ereport(ERROR,
190+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
191+
errmsg("Cannot acquire %d kB of shared memory",
192+
max_ispell_mem_size_kb)));
193+
}
188194
memset(segment,0,max_ispell_mem_size());
189195

190196
#ifPG_VERSION_NUM >=90600
@@ -288,13 +294,9 @@ static void
288294
init_shared_dict(DictInfo*info,char*dictFile,char*affFile,char*stopFile)
289295
{
290296
intsize;
291-
292297
SharedIspellDict*shdict=NULL;
293298
SharedStopList*shstop=NULL;
294299

295-
IspellDict*dict;
296-
StopListstoplist;
297-
298300
/* DICTIONARY + AFFIXES */
299301

300302
/* TODO This should probably check that the filenames are not NULL, and maybe that
@@ -313,6 +315,8 @@ init_shared_dict(DictInfo *info, char *dictFile, char *affFile, char *stopFile)
313315
/* load the dictionary (word list) if not yet defined */
314316
if (shdict==NULL)
315317
{
318+
IspellDict*dict;
319+
316320
dict= (IspellDict*)palloc0(sizeof(IspellDict));
317321

318322
NIStartBuild(dict);
@@ -383,6 +387,8 @@ init_shared_dict(DictInfo *info, char *dictFile, char *affFile, char *stopFile)
383387
/* load the stopwords if not yet defined */
384388
if (shstop==NULL)
385389
{
390+
StopListstoplist;
391+
386392
readstoplist(stopFile,&stoplist,lowerstr);
387393

388394
size=sizeStopList(&stoplist,stopFile);
@@ -407,11 +413,14 @@ init_shared_dict(DictInfo *info, char *dictFile, char *affFile, char *stopFile)
407413
info->lookup=GetCurrentTimestamp();
408414

409415
memcpy(info->dictFile,dictFile,strlen(dictFile)+1);
410-
memcpy(info->affixFile,dictFile,strlen(affFile)+1);
416+
memcpy(info->affixFile,affFile,strlen(affFile)+1);
411417
if (stopFile!=NULL)
412-
memcpy(info->stopFile,dictFile,strlen(stopFile)+1);
418+
memcpy(info->stopFile,stopFile,strlen(stopFile)+1);
413419
else
414420
memset(info->stopFile,0,sizeof(info->stopFile));
421+
422+
/* save current context as long-lived */
423+
info->saveCntx=CurrentMemoryContext;
415424
}
416425

417426
Datumdispell_init(PG_FUNCTION_ARGS);
@@ -498,6 +507,9 @@ dispell_mem_used(PG_FUNCTION_ARGS)
498507
* The StopWords parameter is optional, the two other are required.
499508
*
500509
* If any of the filenames are incorrect, the call to init_shared_dict will fail.
510+
*
511+
* Do not call it directly - it saves current memory context as long-lived
512+
* context.
501513
*/
502514
Datum
503515
dispell_init(PG_FUNCTION_ARGS)
@@ -586,7 +598,7 @@ dispell_lexize(PG_FUNCTION_ARGS)
586598
char*txt;
587599
TSLexeme*res;
588600
TSLexeme*ptr,
589-
*cptr;
601+
*cptr;
590602

591603
if (len <=0)
592604
PG_RETURN_POINTER(NULL);
@@ -599,11 +611,27 @@ dispell_lexize(PG_FUNCTION_ARGS)
599611
/* do we need to reinit the dictionary? was the dict reset since the lookup */
600612
if (timestamp_cmp_internal(info->lookup,segment_info->lastReset)<0)
601613
{
614+
DictInfosaveInfo=*info;
615+
MemoryContextctx;
616+
602617
/* relock in exclusive mode */
603618
LWLockRelease(segment_info->lock);
604619
LWLockAcquire(segment_info->lock,LW_EXCLUSIVE);
605620

606-
init_shared_dict(info,info->dictFile,info->affixFile,info->stopFile);
621+
/*
622+
* info is allocated in info->saveCntx, so that's why we use a copy of
623+
* info here
624+
*/
625+
626+
MemoryContextResetAndDeleteChildren(saveInfo.saveCntx);
627+
ctx=MemoryContextSwitchTo(saveInfo.saveCntx);
628+
629+
info=palloc0(sizeof(*info));
630+
631+
init_shared_dict(info,saveInfo.dictFile,
632+
saveInfo.affixFile,saveInfo.stopFile);
633+
634+
MemoryContextSwitchTo(ctx);
607635
}
608636

609637
res=NINormalizeWord(&(info->dict),txt);
@@ -697,13 +725,13 @@ copySPNode(SPNode *node)
697725
SPNode*copy=NULL;
698726

699727
if (node==NULL)
700-
returnNULL;
728+
returnNULL;
701729

702730
copy= (SPNode*)shalloc(offsetof(SPNode,data)+sizeof(SPNodeData)*node->length);
703731
memcpy(copy,node, offsetof(SPNode,data)+sizeof(SPNodeData)*node->length);
704732

705733
for (i=0;i<node->length;i++)
706-
copy->data[i].node=copySPNode(node->data[i].node);
734+
copy->data[i].node=copySPNode(node->data[i].node);
707735

708736
returncopy;
709737
}
@@ -715,7 +743,7 @@ sizeSPNode(SPNode *node)
715743
intsize=0;
716744

717745
if (node==NULL)
718-
return0;
746+
return0;
719747

720748
size=MAXALIGN(offsetof(SPNode,data)+sizeof(SPNodeData)*node->length);
721749

@@ -815,7 +843,7 @@ sizeIspellDict(IspellDict *dict, char *dictFile, char *affixFile)
815843
/* copy affix data */
816844
size+=MAXALIGN(sizeof(char*)*dict->nAffixData);
817845
for (i=0;i<dict->nAffixData;i++)
818-
size+=MAXALIGN(sizeof(char)*strlen(dict->AffixData[i])+1);
846+
size+=MAXALIGN(sizeof(char)*strlen(dict->AffixData[i])+1);
819847

820848
returnsize;
821849
}
@@ -842,10 +870,10 @@ dispell_list_dicts(PG_FUNCTION_ARGS)
842870

843871
/* Build a tuple descriptor for our result type */
844872
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
845-
ereport(ERROR,
846-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
847-
errmsg("function returning record called in context "
848-
"that cannot accept type record")));
873+
ereport(ERROR,
874+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
875+
errmsg("function returning record called in context "
876+
"that cannot accept type record")));
849877

850878
/*
851879
* generate attribute metadata needed later to produce tuples from raw

‎src/shared_ispell.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define__SHARED_ISPELL_H__
33

44
#include"storage/lwlock.h"
5+
#include"utils/memutils.h"
56
#include"utils/timestamp.h"
67
#include"tsearch/dicts/spell.h"
78
#include"tsearch/ts_public.h"
@@ -66,6 +67,9 @@ typedef struct DictInfo
6667
SharedIspellDict*shdict;
6768
IspellDictdict;
6869
SharedStopList*shstop;
70+
71+
/* MemoryContext of dict local content */
72+
MemoryContextsaveCntx;
6973
}DictInfo;
7074

71-
#endif
75+
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp