about summary refs log tree commit diff
path: root/libio/iogetdelim.c
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2022-12-19 12:40:45 +0100
committerAndreas Schwab <schwab@suse.de>2023-01-02 10:58:49 +0100
commita09183aed7bb8ace211e042b2e6e982bcc004957 (patch)
tree7b82a3d4952b5623087f7368fddeea81570f4f23 /libio/iogetdelim.c
parent289b098c9e21e2805e3835f9b5780235ab14a290 (diff)
downloadglibc-a09183aed7bb8ace211e042b2e6e982bcc004957.tar.gz
glibc-a09183aed7bb8ace211e042b2e6e982bcc004957.tar.xz
glibc-a09183aed7bb8ace211e042b2e6e982bcc004957.zip
getdelim: ensure error indicator is set on error (bug 29917)
POSIX requires that getdelim and getline set the error indicator on the
stream when an error occured, in addition to setting errno.
Diffstat (limited to 'libio/iogetdelim.c')
-rw-r--r--libio/iogetdelim.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/libio/iogetdelim.c b/libio/iogetdelim.c
index b6c4c07b45..591526e9c1 100644
--- a/libio/iogetdelim.c
+++ b/libio/iogetdelim.c
@@ -43,11 +43,6 @@ __getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
   ssize_t cur_len = 0;
   ssize_t len;
 
-  if (lineptr == NULL || n == NULL)
-    {
-      __set_errno (EINVAL);
-      return -1;
-    }
   CHECK_FILE (fp, -1);
   _IO_acquire_lock (fp);
   if (_IO_ferror_unlocked (fp))
@@ -56,12 +51,21 @@ __getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
       goto unlock_return;
     }
 
+  if (lineptr == NULL || n == NULL)
+    {
+      __set_errno (EINVAL);
+      fseterr_unlocked (fp);
+      result = -1;
+      goto unlock_return;
+    }
+
   if (*lineptr == NULL || *n == 0)
     {
       *n = 120;
       *lineptr = (char *) malloc (*n);
       if (*lineptr == NULL)
 	{
+	  fseterr_unlocked (fp);
 	  result = -1;
 	  goto unlock_return;
 	}
@@ -88,6 +92,7 @@ __getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
       if (__glibc_unlikely (len >= SSIZE_MAX - cur_len))
 	{
 	  __set_errno (EOVERFLOW);
+	  fseterr_unlocked (fp);
 	  result = -1;
 	  goto unlock_return;
 	}
@@ -102,6 +107,7 @@ __getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
 	  new_lineptr = (char *) realloc (*lineptr, needed);
 	  if (new_lineptr == NULL)
 	    {
+	      fseterr_unlocked (fp);
 	      result = -1;
 	      goto unlock_return;
 	    }