Skip to content

Commit 70d6226

Browse files
committed
Use portal pinning in PL/Perl and PL/Python
PL/pgSQL "pins" internally generated portals so that user code cannot close them by guessing their names. Add this functionality to PL/Perl and PL/Python as well, preventing users from manually closing cursors created by spi_query and plpy.cursor, respectively. (PL/Tcl does not currently offer any cursor functionality.)
1 parent 5115854 commit 70d6226

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

src/pl/plperl/plperl.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3406,6 +3406,8 @@ plperl_spi_query(char *query)
34063406
SPI_result_code_string(SPI_result));
34073407
cursor = cstr2sv(portal->name);
34083408

3409+
PinPortal(portal);
3410+
34093411
/* Commit the inner transaction, return to outer xact context */
34103412
ReleaseCurrentSubTransaction();
34113413
MemoryContextSwitchTo(oldcontext);
@@ -3469,6 +3471,7 @@ plperl_spi_fetchrow(char *cursor)
34693471
SPI_cursor_fetch(p, true, 1);
34703472
if (SPI_processed == 0)
34713473
{
3474+
UnpinPortal(p);
34723475
SPI_cursor_close(p);
34733476
row = &PL_sv_undef;
34743477
}
@@ -3520,7 +3523,10 @@ plperl_spi_cursor_close(char *cursor)
35203523
p = SPI_cursor_find(cursor);
35213524

35223525
if (p)
3526+
{
3527+
UnpinPortal(p);
35233528
SPI_cursor_close(p);
3529+
}
35243530
}
35253531

35263532
SV *
@@ -3884,6 +3890,8 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv)
38843890

38853891
cursor = cstr2sv(portal->name);
38863892

3893+
PinPortal(portal);
3894+
38873895
/* Commit the inner transaction, return to outer xact context */
38883896
ReleaseCurrentSubTransaction();
38893897
MemoryContextSwitchTo(oldcontext);

src/pl/plpython/plpy_cursorobject.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ PLy_cursor_query(const char *query)
151151

152152
cursor->portalname = MemoryContextStrdup(cursor->mcxt, portal->name);
153153

154+
PinPortal(portal);
155+
154156
PLy_spi_subtransaction_commit(oldcontext, oldowner);
155157
}
156158
PG_CATCH();
@@ -266,6 +268,8 @@ PLy_cursor_plan(PyObject *ob, PyObject *args)
266268

267269
cursor->portalname = MemoryContextStrdup(cursor->mcxt, portal->name);
268270

271+
PinPortal(portal);
272+
269273
PLy_spi_subtransaction_commit(oldcontext, oldowner);
270274
}
271275
PG_CATCH();
@@ -317,7 +321,10 @@ PLy_cursor_dealloc(PyObject *arg)
317321
portal = GetPortalByName(cursor->portalname);
318322

319323
if (PortalIsValid(portal))
324+
{
325+
UnpinPortal(portal);
320326
SPI_cursor_close(portal);
327+
}
321328
cursor->closed = true;
322329
}
323330
if (cursor->mcxt)
@@ -508,6 +515,7 @@ PLy_cursor_close(PyObject *self, PyObject *unused)
508515
return NULL;
509516
}
510517

518+
UnpinPortal(portal);
511519
SPI_cursor_close(portal);
512520
cursor->closed = true;
513521
}

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