1
/*-------------------------------------------------------------------------
4
* various support functions
6
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
10
* src/backend/tsearch/ts_utils.c
12
*-------------------------------------------------------------------------
19
#include "miscadmin.h"
20
#include "tsearch/ts_locale.h"
21
#include "tsearch/ts_public.h"
22
#include "tsearch/ts_utils.h"
23
#include "utils/builtins.h"
27
* Given the base name and extension of a tsearch config file, return
28
* its full path name. The base name is assumed to be user-supplied,
29
* and is checked to prevent pathname attacks. The extension is assumed
32
* The result is a palloc'd string.
35
get_tsearch_config_filename(const char *basename,
36
const char *extension)
38
char sharepath[MAXPGPATH];
42
* We limit the basename to contain a-z, 0-9, and underscores. This may
43
* be overly restrictive, but we don't want to allow access to anything
44
* outside the tsearch_data directory, so for instance '/' *must* be
45
* rejected, and on some platforms '\' and ':' are risky as well. Allowing
46
* uppercase might result in incompatible behavior between case-sensitive
47
* and case-insensitive filesystems, and non-ASCII characters create other
48
* interesting risks, so on the whole a tight policy seems best.
50
if (strspn(basename, "abcdefghijklmnopqrstuvwxyz0123456789_") != strlen(basename))
52
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
53
errmsg("invalid text search configuration file name \"%s\"",
56
get_share_path(my_exec_path, sharepath);
57
result = palloc(MAXPGPATH);
58
snprintf(result, MAXPGPATH, "%s/tsearch_data/%s.%s",
59
sharepath, basename, extension);
65
comparestr(const void *a, const void *b)
67
return strcmp(*(char **) a, *(char **) b);
71
* Reads a stop-word file. Each word is run through 'wordop'
72
* function, if given. wordop may either modify the input in-place,
73
* or palloc a new version.
76
readstoplist(const char *fname, StopList *s, char *(*wordop) (const char *))
83
char *filename = get_tsearch_config_filename(fname, "stop");
84
tsearch_readline_state trst;
88
if (!tsearch_readline_begin(&trst, filename))
90
(errcode(ERRCODE_CONFIG_FILE_ERROR),
91
errmsg("could not open stop-word file \"%s\": %m",
94
while ((line = tsearch_readline(&trst)) != NULL)
98
/* Trim trailing space */
99
while (*pbuf && !t_isspace(pbuf))
100
pbuf += pg_mblen(pbuf);
103
/* Skip empty lines */
110
if (s->len >= reallen)
115
stop = (char **) palloc(sizeof(char *) * reallen);
120
stop = (char **) repalloc((void *) stop,
121
sizeof(char *) * reallen);
127
stop[s->len] = wordop(line);
128
if (stop[s->len] != line)
137
tsearch_readline_end(&trst);
143
/* Sort to allow binary searching */
144
if (s->stop && s->len > 0)
145
qsort(s->stop, s->len, sizeof(char *), comparestr);
149
searchstoplist(StopList *s, char *key)
151
return (s->stop && s->len > 0 &&
152
bsearch(&key, s->stop, s->len,
153
sizeof(char *), comparestr)) ? true : false;