You signed in with another tab or window.Reload to refresh your session.You signed out in another tab or window.Reload to refresh your session.You switched accounts on another tab or window.Reload to refresh your session.Dismiss alert
Use PQescapeString to ensure that tab-completion queries are not messed
up by quotes or backslashes in words that are being matched to databasenames (per gripe from Ian Barwick, though I didn't use his patch).Also fix possible memory leakage if _complete_with_query isn't run tocompletion (not clear if that can happen or not, but be safe).
/* These variables are used to pass information into the completion functions.
94
97
Realizing that this is the cardinal sin of programming, I don't see a better
95
98
way. */
96
-
char*completion_charp;/* if you need to pass a string */
97
-
char**completion_charpp;/* if you need to pass a list of strings */
98
-
char*completion_info_charp;/* if you need to pass another
99
+
staticchar*completion_charp;/* if you need to pass a string */
100
+
staticchar**completion_charpp;/* if you need to pass a list of strings */
101
+
staticchar*completion_info_charp;/* if you need to pass another
99
102
* string */
100
103
101
104
/* Store how many records from a database query we want to return at most
@@ -124,7 +127,10 @@ initialize_readline(void)
124
127
/*
125
128
* Queries to get lists of names of various kinds of things, possibly
126
129
* restricted to names matching a partially entered name. In these queries,
127
-
* the %s will be replaced by the text entered so far, the %d by its length.
130
+
* %s will be replaced by the text entered so far (suitably escaped to
131
+
* become a SQL literal string). %d will be replaced by the length of the
132
+
* string (in unescaped form). Beware that the allowed sequences of %s and
133
+
* %d are determined by _complete_from_query().
128
134
*/
129
135
130
136
#defineQuery_for_list_of_aggregates \
@@ -401,6 +407,15 @@ initialize_readline(void)
401
407
" FROM pg_catalog.pg_user "\
402
408
" WHERE substr(usename,1,%d)='%s'"
403
409
410
+
/* the silly-looking length condition is just to eat up the current word */
411
+
#defineQuery_for_table_owning_index \
412
+
"SELECT c1.relname "\
413
+
" FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\
414
+
" WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\
415
+
" and (%d = length('%s'))"\
416
+
" and c2.relname='%s'"\
417
+
" and pg_catalog.pg_table_is_visible(c2.oid)"
418
+
404
419
/* This is a list of all "things" in Pgsql, which can show up after CREATE or
405
420
DROP; and there is also a query to get a list of them.
406
421
*/
@@ -754,15 +769,8 @@ psql_completion(char *text, int start, int end)
754
769
elseif (strcasecmp(prev3_wd,"CLUSTER")==0&&
755
770
strcasecmp(prev_wd,"ON")==0)
756
771
{
757
-
charquery_buffer[BUF_SIZE];/* Some room to build
758
-
* queries. */
759
-
760
-
if (snprintf(query_buffer,BUF_SIZE,
761
-
"SELECT c1.relname FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid and c2.relname='%s' and pg_catalog.pg_table_is_visible(c2.oid)",
* If this is the first time for this completion, we fetch a list of
1442
1451
* our "things" from the backend.
1443
1452
*/
1444
1453
if (state==0)
1445
1454
{
1455
+
charquery_buffer[BUF_SIZE];
1456
+
char*e_text;
1457
+
char*e_info_charp;
1458
+
1446
1459
list_index=0;
1447
1460
string_length=strlen(text);
1448
1461
1462
+
/* Free any prior result */
1463
+
PQclear(result);
1464
+
result=NULL;
1465
+
1449
1466
/* Need to have a query */
1450
1467
if (completion_charp==NULL)
1451
1468
returnNULL;
1452
1469
1453
-
if (is_schema_query)
1470
+
/* Set up suitably-escaped copies of textual inputs */
1471
+
if (text)
1454
1472
{
1455
-
if (snprintf(query_buffer,BUF_SIZE,completion_charp,string_length,text,string_length,text,string_length,text,text,string_length,text,string_length,text)==-1)
1456
-
{
1457
-
ERROR_QUERY_TOO_LONG;
1473
+
e_text= (char*)malloc(strlen(text)*2+1);
1474
+
if (!e_text)
1458
1475
returnNULL;
1459
-
}
1476
+
PQescapeString(e_text,text,strlen(text));
1460
1477
}
1461
1478
else
1479
+
e_text=NULL;
1480
+
1481
+
if (completion_info_charp)
1462
1482
{
1463
-
if (snprintf(query_buffer,BUF_SIZE,completion_charp,string_length,text,completion_info_charp)==-1)