From cfbcb6bb21ed9bf06ffba723756ba24d440eb1ef Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 21 Nov 2000 21:51:58 +0000 Subject: [PATCH] Make the world safe for unsigned OIDs. --- contrib/lo/lo.c | 41 +++++++++++++++++------------------------ contrib/lo/lo.sql.in | 22 +++++++++++----------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/contrib/lo/lo.c b/contrib/lo/lo.c index 5de00ad5ca..6f45394ac6 100644 --- a/contrib/lo/lo.c +++ b/contrib/lo/lo.c @@ -1,26 +1,29 @@ /* * PostgreSQL type definitions for managed LargeObjects. * - * $Id: lo.c,v 1.5 2000/11/20 20:36:55 tgl Exp $ + * $Header: /cvsroot/pgsql/contrib/lo/lo.c,v 1.6 2000/11/21 21:51:58 tgl Exp $ * */ +#include "postgres.h" + #include -#include -#include +#include "utils/palloc.h" /* Required for largeobjects */ -#include -#include +#include "libpq/libpq-fs.h" +#include "libpq/be-fsstubs.h" /* Required for SPI */ -#include +#include "executor/spi.h" /* Required for triggers */ -#include +#include "commands/trigger.h" + + +#define atooid(x) ((Oid) strtoul((x), NULL, 10)) -/* required for tolower() */ /* * This is the internal storage format for managed large objects @@ -40,7 +43,7 @@ Blob *lo(Oid oid); /* Return Blob based on oid */ Datum lo_manage(PG_FUNCTION_ARGS); /* Trigger handler */ /* - * This creates a large object, and set's its OID to the value in the + * This creates a large object, and sets its OID to the value in the * supplied string. * * If the string is empty, then a new LargeObject is created, and its oid @@ -55,20 +58,13 @@ lo_in(char *str) if (strlen(str) > 0) { - - count = sscanf(str, "%d", &oid); + count = sscanf(str, "%u", &oid); if (count < 1) - { elog(ERROR, "lo_in: error in parsing \"%s\"", str); - return (NULL); - } - if (oid < 0) - { + if (oid == InvalidOid) elog(ERROR, "lo_in: illegal oid \"%s\"", str); - return (NULL); - } } else { @@ -79,10 +75,7 @@ lo_in(char *str) oid = DatumGetObjectId(DirectFunctionCall1(lo_creat, Int32GetDatum(INV_READ | INV_WRITE))); if (oid == InvalidOid) - { elog(ERROR, "lo_in: InvalidOid returned from lo_creat"); - return (NULL); - } } result = (Blob *) palloc(sizeof(Blob)); @@ -104,7 +97,7 @@ lo_out(Blob * addr) return (NULL); result = (char *) palloc(32); - sprintf(result, "%d", *addr); + sprintf(result, "%u", *addr); return (result); } @@ -190,7 +183,7 @@ lo_manage(PG_FUNCTION_ARGS) if ((orig != newv && (orig == NULL || newv == NULL)) || (orig != NULL && newv != NULL && strcmp(orig, newv))) DirectFunctionCall1(lo_unlink, - ObjectIdGetDatum((Oid) atoi(orig))); + ObjectIdGetDatum(atooid(orig))); if (newv) pfree(newv); @@ -211,7 +204,7 @@ lo_manage(PG_FUNCTION_ARGS) if (orig != NULL) { DirectFunctionCall1(lo_unlink, - ObjectIdGetDatum((Oid) atoi(orig))); + ObjectIdGetDatum(atooid(orig))); pfree(orig); } diff --git a/contrib/lo/lo.sql.in b/contrib/lo/lo.sql.in index 9b340b196f..f9fed597fd 100644 --- a/contrib/lo/lo.sql.in +++ b/contrib/lo/lo.sql.in @@ -1,7 +1,7 @@ -- -- PostgreSQL code for LargeObjects -- --- $Id: lo.sql.in,v 1.5 2000/11/20 20:36:55 tgl Exp $ +-- $Id: lo.sql.in,v 1.6 2000/11/21 21:51:58 tgl Exp $ -- -- -- Create the data type @@ -33,6 +33,15 @@ create function lo_oid(lo) as 'MODULE_PATHNAME' language 'c'; +-- same function, named to allow it to be used as a type coercion, eg: +-- create table a (image lo); +-- select image::oid from a; +-- +create function oid(lo) + returns oid + as 'MODULE_PATHNAME', 'lo_oid' + language 'c'; + -- this allows us to convert an oid to a managed lo object -- ie: insert into test values (lo_import('/fullpath/file')::lo); create function lo(oid) @@ -44,13 +53,4 @@ create function lo(oid) create function lo_manage() returns opaque as 'MODULE_PATHNAME' - language 'C'; - --- This allows us to map lo to oid --- --- eg: --- create table a (image lo); --- select image::oid from a; --- -create function oid(lo) returns oid as 'select lo_oid($1)' language 'sql'; - + language 'c';