When looking at the recent changes in this file I noticed that the
presence of both ber_read() and ber_readbuf() was due to an incomplete
cleanup from my part.

  revision 1.32
  date: 2018/02/08 18:02:06;  author: jca;  state: Exp;  lines: +6 -22;  
commitid: YNQMco5lCS8YEifQ;
  Kill ber.c support for direct fd read/writes

  This mechanism is already unused and annotated with lots of XXX's, no
  need to keep it around.  ok claudio@

I think the recent changes would have been easier if the code had been
further simplified.  Here's a shot at it:
- stop looping in ber_read(), there is no fd read to handle any more so
  calling ber_readbuf() once is enough
- amend the condition which decides whether to return -1/ECANCELED:
  - it makes little sense to pass a buffer length size of zero to
  ber_read(), but then we should probably return 0 and not -1/ECANCELED
  - I don't think we should perform partial reads: either the caller
  function has the data it asked for, or nothing.  Allowing partial
  reads means that we're putting the burden of handling an incomplete
  buffer on the caller.
- inline what remains of ber_readbuf() in ber_read()

regress tests for ldapd and snmpd pass, it would be cool to have test
reports from people who actually use those programs (ldap, ldapd, snmpd
and ypldap).

Looking for reviews and oks.  The diff is not that long but I can split
it in smaller parts if it helps.


Index: usr.bin/ldap/ber.c
===================================================================
RCS file: /d/cvs/src/usr.bin/ldap/ber.c,v
retrieving revision 1.11
diff -u -p -r1.11 ber.c
--- usr.bin/ldap/ber.c  4 Jul 2018 15:21:24 -0000       1.11
+++ usr.bin/ldap/ber.c  6 Jul 2018 11:50:24 -0000
@@ -31,8 +31,6 @@
 
 #include "ber.h"
 
-#define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
-
 #define BER_TYPE_CONSTRUCTED   0x20    /* otherwise primitive */
 #define BER_TYPE_SINGLE_MAX    30
 #define BER_TAG_MASK           0x1f
@@ -48,7 +46,6 @@ static ssize_t        get_id(struct ber *b, uns
     int *cstruct);
 static ssize_t get_len(struct ber *b, ssize_t *len);
 static ssize_t ber_read_element(struct ber *ber, struct ber_element *elm);
-static ssize_t ber_readbuf(struct ber *b, void *buf, size_t nbytes);
 static ssize_t ber_getc(struct ber *b, u_char *c);
 static ssize_t ber_read(struct ber *ber, void *buf, size_t len);
 
@@ -1208,28 +1205,6 @@ ber_read_element(struct ber *ber, struct
        return totlen;
 }
 
-static ssize_t
-ber_readbuf(struct ber *b, void *buf, size_t nbytes)
-{
-       size_t   sz, len;
-
-       if (b->br_rbuf == NULL)
-               return -1;
-
-       sz = b->br_rend - b->br_rptr;
-       len = MINIMUM(nbytes, sz);
-       if (len == 0) {
-               errno = ECANCELED;
-               return (-1);    /* end of buffer and parser wants more data */
-       }
-
-       bcopy(b->br_rptr, buf, len);
-       b->br_rptr += len;
-       b->br_offs += len;
-
-       return (len);
-}
-
 void
 ber_set_readbuf(struct ber *b, void *buf, size_t len)
 {
@@ -1269,23 +1244,28 @@ ber_free(struct ber *b)
 static ssize_t
 ber_getc(struct ber *b, u_char *c)
 {
-       return ber_readbuf(b, c, 1);
+       return ber_read(b, c, 1);
 }
 
 static ssize_t
 ber_read(struct ber *ber, void *buf, size_t len)
 {
-       u_char *b = buf;
-       ssize_t r, remain = len;
+       size_t  sz;
 
-       while (remain > 0) {
-               r = ber_readbuf(ber, b, remain);
-               if (r == -1)
-                       return -1;
-               b += r;
-               remain -= r;
+       if (ber->br_rbuf == NULL)
+               return -1;
+
+       sz = ber->br_rend - ber->br_rptr;
+       if (len > sz) {
+               errno = ECANCELED;
+               return -1;      /* parser wants more data than available */
        }
-       return (b - (u_char *)buf);
+
+       bcopy(ber->br_rptr, buf, len);
+       ber->br_rptr += len;
+       ber->br_offs += len;
+
+       return len;
 }
 
 int
Index: usr.sbin/ldapd/ber.c
===================================================================
RCS file: /d/cvs/src/usr.sbin/ldapd/ber.c,v
retrieving revision 1.21
diff -u -p -r1.21 ber.c
--- usr.sbin/ldapd/ber.c        4 Jul 2018 15:21:24 -0000       1.21
+++ usr.sbin/ldapd/ber.c        6 Jul 2018 11:47:55 -0000
@@ -31,8 +31,6 @@
 
 #include "ber.h"
 
-#define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
-
 #define BER_TYPE_CONSTRUCTED   0x20    /* otherwise primitive */
 #define BER_TYPE_SINGLE_MAX    30
 #define BER_TAG_MASK           0x1f
@@ -48,7 +46,6 @@ static ssize_t        get_id(struct ber *b, uns
     int *cstruct);
 static ssize_t get_len(struct ber *b, ssize_t *len);
 static ssize_t ber_read_element(struct ber *ber, struct ber_element *elm);
-static ssize_t ber_readbuf(struct ber *b, void *buf, size_t nbytes);
 static ssize_t ber_getc(struct ber *b, u_char *c);
 static ssize_t ber_read(struct ber *ber, void *buf, size_t len);
 
@@ -1208,28 +1205,6 @@ ber_read_element(struct ber *ber, struct
        return totlen;
 }
 
-static ssize_t
-ber_readbuf(struct ber *b, void *buf, size_t nbytes)
-{
-       size_t   sz, len;
-
-       if (b->br_rbuf == NULL)
-               return -1;
-
-       sz = b->br_rend - b->br_rptr;
-       len = MINIMUM(nbytes, sz);
-       if (len == 0) {
-               errno = ECANCELED;
-               return (-1);    /* end of buffer and parser wants more data */
-       }
-
-       bcopy(b->br_rptr, buf, len);
-       b->br_rptr += len;
-       b->br_offs += len;
-
-       return (len);
-}
-
 void
 ber_set_readbuf(struct ber *b, void *buf, size_t len)
 {
@@ -1269,23 +1244,28 @@ ber_free(struct ber *b)
 static ssize_t
 ber_getc(struct ber *b, u_char *c)
 {
-       return ber_readbuf(b, c, 1);
+       return ber_read(b, c, 1);
 }
 
 static ssize_t
 ber_read(struct ber *ber, void *buf, size_t len)
 {
-       u_char *b = buf;
-       ssize_t r, remain = len;
+       size_t  sz;
 
-       while (remain > 0) {
-               r = ber_readbuf(ber, b, remain);
-               if (r == -1)
-                       return -1;
-               b += r;
-               remain -= r;
+       if (ber->br_rbuf == NULL)
+               return -1;
+
+       sz = ber->br_rend - ber->br_rptr;
+       if (len > sz) {
+               errno = ECANCELED;
+               return -1;      /* parser wants more data than available */
        }
-       return (b - (u_char *)buf);
+
+       bcopy(ber->br_rptr, buf, len);
+       ber->br_rptr += len;
+       ber->br_offs += len;
+
+       return len;
 }
 
 int
Index: usr.sbin/snmpd/ber.c
===================================================================
RCS file: /d/cvs/src/usr.sbin/snmpd/ber.c,v
retrieving revision 1.40
diff -u -p -r1.40 ber.c
--- usr.sbin/snmpd/ber.c        4 Jul 2018 15:21:24 -0000       1.40
+++ usr.sbin/snmpd/ber.c        6 Jul 2018 11:50:18 -0000
@@ -31,8 +31,6 @@
 
 #include "ber.h"
 
-#define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
-
 #define BER_TYPE_CONSTRUCTED   0x20    /* otherwise primitive */
 #define BER_TYPE_SINGLE_MAX    30
 #define BER_TAG_MASK           0x1f
@@ -48,7 +46,6 @@ static ssize_t        get_id(struct ber *b, uns
     int *cstruct);
 static ssize_t get_len(struct ber *b, ssize_t *len);
 static ssize_t ber_read_element(struct ber *ber, struct ber_element *elm);
-static ssize_t ber_readbuf(struct ber *b, void *buf, size_t nbytes);
 static ssize_t ber_getc(struct ber *b, u_char *c);
 static ssize_t ber_read(struct ber *ber, void *buf, size_t len);
 
@@ -1208,28 +1205,6 @@ ber_read_element(struct ber *ber, struct
        return totlen;
 }
 
-static ssize_t
-ber_readbuf(struct ber *b, void *buf, size_t nbytes)
-{
-       size_t   sz, len;
-
-       if (b->br_rbuf == NULL)
-               return -1;
-
-       sz = b->br_rend - b->br_rptr;
-       len = MINIMUM(nbytes, sz);
-       if (len == 0) {
-               errno = ECANCELED;
-               return (-1);    /* end of buffer and parser wants more data */
-       }
-
-       bcopy(b->br_rptr, buf, len);
-       b->br_rptr += len;
-       b->br_offs += len;
-
-       return (len);
-}
-
 void
 ber_set_readbuf(struct ber *b, void *buf, size_t len)
 {
@@ -1269,23 +1244,28 @@ ber_free(struct ber *b)
 static ssize_t
 ber_getc(struct ber *b, u_char *c)
 {
-       return ber_readbuf(b, c, 1);
+       return ber_read(b, c, 1);
 }
 
 static ssize_t
 ber_read(struct ber *ber, void *buf, size_t len)
 {
-       u_char *b = buf;
-       ssize_t r, remain = len;
+       size_t  sz;
 
-       while (remain > 0) {
-               r = ber_readbuf(ber, b, remain);
-               if (r == -1)
-                       return -1;
-               b += r;
-               remain -= r;
+       if (ber->br_rbuf == NULL)
+               return -1;
+
+       sz = ber->br_rend - ber->br_rptr;
+       if (len > sz) {
+               errno = ECANCELED;
+               return -1;      /* parser wants more data than available */
        }
-       return (b - (u_char *)buf);
+
+       bcopy(ber->br_rptr, buf, len);
+       ber->br_rptr += len;
+       ber->br_offs += len;
+
+       return len;
 }
 
 int
Index: usr.sbin/ypldap/ber.c
===================================================================
RCS file: /d/cvs/src/usr.sbin/ypldap/ber.c,v
retrieving revision 1.23
diff -u -p -r1.23 ber.c
--- usr.sbin/ypldap/ber.c       4 Jul 2018 15:21:24 -0000       1.23
+++ usr.sbin/ypldap/ber.c       8 Jul 2018 13:34:13 -0000
@@ -31,8 +31,6 @@
 
 #include "ber.h"
 
-#define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
-
 #define BER_TYPE_CONSTRUCTED   0x20    /* otherwise primitive */
 #define BER_TYPE_SINGLE_MAX    30
 #define BER_TAG_MASK           0x1f
@@ -48,7 +46,6 @@ static ssize_t        get_id(struct ber *b, uns
     int *cstruct);
 static ssize_t get_len(struct ber *b, ssize_t *len);
 static ssize_t ber_read_element(struct ber *ber, struct ber_element *elm);
-static ssize_t ber_readbuf(struct ber *b, void *buf, size_t nbytes);
 static ssize_t ber_getc(struct ber *b, u_char *c);
 static ssize_t ber_read(struct ber *ber, void *buf, size_t len);
 
@@ -1208,28 +1205,6 @@ ber_read_element(struct ber *ber, struct
        return totlen;
 }
 
-static ssize_t
-ber_readbuf(struct ber *b, void *buf, size_t nbytes)
-{
-       size_t   sz, len;
-
-       if (b->br_rbuf == NULL)
-               return -1;
-
-       sz = b->br_rend - b->br_rptr;
-       len = MINIMUM(nbytes, sz);
-       if (len == 0) {
-               errno = ECANCELED;
-               return (-1);    /* end of buffer and parser wants more data */
-       }
-
-       bcopy(b->br_rptr, buf, len);
-       b->br_rptr += len;
-       b->br_offs += len;
-
-       return (len);
-}
-
 void
 ber_set_readbuf(struct ber *b, void *buf, size_t len)
 {
@@ -1269,23 +1244,28 @@ ber_free(struct ber *b)
 static ssize_t
 ber_getc(struct ber *b, u_char *c)
 {
-       return ber_readbuf(b, c, 1);
+       return ber_read(b, c, 1);
 }
 
 static ssize_t
 ber_read(struct ber *ber, void *buf, size_t len)
 {
-       u_char *b = buf;
-       ssize_t r, remain = len;
+       size_t  sz;
 
-       while (remain > 0) {
-               r = ber_readbuf(ber, b, remain);
-               if (r == -1)
-                       return -1;
-               b += r;
-               remain -= r;
+       if (ber->br_rbuf == NULL)
+               return -1;
+
+       sz = ber->br_rend - ber->br_rptr;
+       if (len > sz) {
+               errno = ECANCELED;
+               return -1;      /* parser wants more data than available */
        }
-       return (b - (u_char *)buf);
+
+       bcopy(ber->br_rptr, buf, len);
+       ber->br_rptr += len;
+       ber->br_offs += len;
+
+       return len;
 }
 
 int

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to