]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Add solv_fmemopen() function
authorMichael Schroeder <mls@suse.de>
Wed, 3 Jun 2020 12:06:32 +0000 (14:06 +0200)
committerMichael Schroeder <mls@suse.de>
Wed, 3 Jun 2020 12:06:32 +0000 (14:06 +0200)
The solv_xfopen_buf() function we have has the disadvantage
that it updates the buffer pointer/length when reading/writing.
This can easily lead to writing to locations that went out of
scope, like with our usage in testcase.c.

So solv_fmemopen() removes that indirection and directly takes
the buffer pointer and length as arguments. Only reading is
currently supported.

ext/libsolvext.ver
ext/solv_xfopen.c
ext/solv_xfopen.h
ext/testcase.c

index 6423837816d31da4d6a8d6dad6328d6d9672a9ba..5e9b0799948c8b4c3b37865904b74c473c09bc9a 100644 (file)
@@ -55,6 +55,7 @@ SOLV_1.0 {
                rpm_stat_database;
                rpm_state_create;
                rpm_state_free;
+               solv_fmemopen;
                solv_verify_sig;
                solv_xfopen;
                solv_xfopen_buf;
index 4bb4628cdcd8cd5c7592dd5d4ae5e5e37d775329..7e974a91a97abfdecd73dc65ff7043b3f814f688 100644 (file)
@@ -798,6 +798,7 @@ struct bufcookie {
   size_t *buflp;
   char *freemem;
   size_t bufl_int;
+  char *buf_int;
 };
 
 static ssize_t cookie_bufread(void *cookie, char *buf, size_t nbytes)
@@ -870,30 +871,48 @@ solv_xfopen_buf(const char *fn, char **bufp, size_t *buflp, const char *mode)
   return fp;
 }
 
+FILE *
+solv_fmemopen(const char *buf, size_t bufl, const char *mode)
+{
+  struct bufcookie *bc;
+  FILE *fp;
+  if (*mode != 'r')
+    return 0;
+  bc = solv_calloc(1, sizeof(*bc));
+  bc->buf_int = (char *)buf;
+  bc->bufl_int = bufl;
+  bc->bufp = &bc->buf_int;
+  bc->buflp = &bc->bufl_int;
+  fp = cookieopen(bc, mode, cookie_bufread, cookie_bufwrite, cookie_bufclose);
+  if (!strcmp(mode, "rf"))     /* auto-free */
+    bc->freemem = bc->buf_int;
+  if (!fp)
+    cookie_bufclose(bc);
+  return fp;
+}
+
 #else
 
 FILE *
-solv_xfopen_buf(const char *fn, char **bufp, size_t *buflp, const char *mode)
+solv_fmemopen(const char *buf, size_t bufl, const char *mode)
 {
   FILE *fp;
-  size_t l;
   if (*mode != 'r')
     return 0;
-  l = buflp ? *buflp : strlen(*bufp);
   if (!strcmp(mode, "rf"))
     {
-      if (!(fp = fmemopen(0, l, "r+")))
+      if (!(fp = fmemopen(0, bufl, "r+")))
        return 0;
-      if (l && fwrite(*bufp, l, 1, fp) != 1)
+      if (bufl && fwrite(buf, bufl, 1, fp) != 1)
        {
          fclose(fp);
          return 0;
        }
-      solv_free(*bufp);
+      solv_free((char *)buf);
       rewind(fp);
     }
   else
-    fp = fmemopen(*bufp, l, "r");
+    fp = fmemopen((char *)buf, bufl, "r");
   return fp;
 }
 
index aa8740e8ad6c51f3dcdb1c60a80a203d79be8167..613f33178f14079fd7c79c91a943f3a11f095a75 100644 (file)
@@ -12,5 +12,6 @@ extern FILE *solv_xfopen(const char *fn, const char *mode);
 extern FILE *solv_xfopen_fd(const char *fn, int fd, const char *mode);
 extern FILE *solv_xfopen_buf(const char *fn, char **bufp, size_t *buflp, const char *mode);
 extern int   solv_xfopen_iscompressed(const char *fn);
+extern FILE *solv_fmemopen(const char *buf, size_t bufl, const char *mode);
 
 #endif
index d6c4a577828245475765d8665dd51dfb309b1b79..16727068fc62fc9defdd9b1c3e7c921c7f1841b3 100644 (file)
@@ -2071,7 +2071,7 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
                {
                  char *idata = read_inline_file(fp, &buf, &bufp, &bufl);
                  rdata = "<inline>";
-                 rfp = solv_xfopen_buf(rdata, &idata, 0, "rf");
+                 rfp = solv_fmemopen(idata, strlen(idata), "rf");
                }
              else
                {