public inbox for [email protected]  
help / color / mirror / Atom feed
From: Chao Li <[email protected]>
To: Postgres hackers <[email protected]>
Subject: Fix a bug in extension_file_exists()
Date: Mon, 9 Feb 2026 17:21:17 +0800
Message-ID: <[email protected]> (raw)

Hi,

I just noticed a bug in extension_file_exists():

```
bool
extension_file_exists(const char *extensionName)
{
	bool		result = false;
	List	   *locations;
	DIR		   *dir;
	struct dirent *de;

	locations = get_extension_control_directories();

	foreach_ptr(char, location, locations) // <== Here type char is wrong
	{
		dir = AllocateDir(location);
```

get_extension_control_directories() returns a list of ExtensionLocation, but the loop iterates it as if it contained char *, which is incorrect. As a result, AllocateDir() and ReadDir() are called with the wrong type.

This bug is only triggered on an error path, when PostgreSQL is deciding whether to emit a hint. For example:
```
evantest=# create function f() returns int LANGUAGE plpython3u as $$return 1$$;
ERROR:  language "plpython3u" does not exist
```
No hint is printed.

With this patch applied:
```
evantest=# create function f() returns int LANGUAGE plpython3u as $$return 1$$;
ERROR:  language "plpython3u" does not exist
HINT:  Use CREATE EXTENSION to load the language into the database.
```
So the hint is shown as intended.

Attached is a patch fixing the iteration to use ExtensionLocation and location->loc consistently.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Attachments:

  [application/octet-stream] v1-0001-Fix-incorrect-iteration-type-in-extension_file_ex.patch (1.2K, ../[email protected]/2-v1-0001-Fix-incorrect-iteration-type-in-extension_file_ex.patch)
  download | inline diff:
From 4a69b519a1b077fc617a2f968bb1dbb2ce2c6806 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Mon, 9 Feb 2026 17:05:57 +0800
Subject: [PATCH v1] Fix incorrect iteration type in extension_file_exists()

Author: Chao Li <[email protected]>
Reviewed-by:
Discussion: https://postgr.es/m/
---
 src/backend/commands/extension.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 596105ee078..f82a7f104c7 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -2557,9 +2557,9 @@ extension_file_exists(const char *extensionName)
 
 	locations = get_extension_control_directories();
 
-	foreach_ptr(char, location, locations)
+	foreach_ptr(ExtensionLocation, location, locations)
 	{
-		dir = AllocateDir(location);
+		dir = AllocateDir(location->loc);
 
 		/*
 		 * If the control directory doesn't exist, we want to silently return
@@ -2571,7 +2571,7 @@ extension_file_exists(const char *extensionName)
 		}
 		else
 		{
-			while ((de = ReadDir(dir, location)) != NULL)
+			while ((de = ReadDir(dir, location->loc)) != NULL)
 			{
 				char	   *extname;
 
-- 
2.50.1 (Apple Git-155)



view thread (5+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected]
  Subject: Re: Fix a bug in extension_file_exists()
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox