- SBUF_TESTING("sbuf_uionew")
- {
- SBUF_SHOULD("reject residuals that are too large")
- {
- struct sbuf *s = NULL;
- uio_t auio = NULL;
- char buf[4];
- int error = 0;
-
- buf[0] = 'A';
- buf[1] = 'B';
- buf[2] = 'C';
- buf[3] = 'D';
-
- auio = uio_create(1, 0, UIO_SYSSPACE, UIO_READ);
- uio_addiov(auio, (user_addr_t)buf, INT_MAX);
-
- s = sbuf_uionew(NULL, auio, &error);
- SBUF_ASSERT_EQ(NULL, s);
- SBUF_ASSERT_EQ(EINVAL, error);
-
- uio_free(auio);
- }
-
- SBUF_SHOULD("initialize using data described by the uio")
- {
- struct sbuf *s = NULL;
- uio_t auio = NULL;
- char buf[4];
- int error = 0;
-
- buf[0] = 'A';
- buf[1] = 'B';
- buf[2] = 'C';
- buf[3] = 'D';
-
- auio = uio_create(1, 0, UIO_SYSSPACE, UIO_WRITE);
- uio_addiov(auio, (user_addr_t)buf, sizeof(buf));
-
- s = sbuf_uionew(NULL, auio, &error);
- SBUF_ASSERT_NE(NULL, s);
- SBUF_ASSERT_EQ(0, error);
- SBUF_ASSERT_EQ(4, s->s_len);
- SBUF_ASSERT_EQ('A', s->s_buf[0]);
- SBUF_ASSERT_EQ('B', s->s_buf[1]);
- SBUF_ASSERT_EQ('C', s->s_buf[2]);
- SBUF_ASSERT_EQ('D', s->s_buf[3]);
-
- sbuf_delete(s);
- uio_free(auio);
- }
-
- SBUF_SHOULD("fail gracefully for bad addresses")
- {
- struct sbuf *s = NULL;
- uio_t auio = NULL;
- int error = 0;
-
- auio = uio_create(1, 0, UIO_USERSPACE, UIO_WRITE);
- uio_addiov(auio, (user_addr_t)0xdeadUL, 123);
-
- s = sbuf_uionew(NULL, auio, &error);
- SBUF_ASSERT_EQ(NULL, s);
- SBUF_ASSERT_NE(0, error);
-
- uio_free(auio);
- }
- }
-
- SBUF_TESTING("sbuf_bcopyin")
- {
- SBUF_SHOULD("succeed when len is zero")
- {
- struct sbuf *s = NULL;
- const void *uptr = (const void *)req->newptr;
-
- s = sbuf_new(NULL, NULL, 16, 0);
- SBUF_ASSERT_EQ(0, sbuf_bcopyin(s, uptr, 0));
- SBUF_ASSERT_EQ(0, s->s_len);
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("succeed in the simple case")
- {
- struct sbuf *s = NULL;
- const void *uptr = (const void *)req->newptr;
- size_t ulen = req->newlen;
-
- s = sbuf_new(NULL, NULL, 16, 0);
- SBUF_ASSERT_EQ(0, sbuf_bcopyin(s, uptr, ulen));
- SBUF_ASSERT_EQ(ulen, (size_t)s->s_len);
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("fail for invalid userland addresses")
- {
- struct sbuf *s = NULL;
- const void *uptr = (const void *)0xdeadUL;
- size_t ulen = req->newlen;
-
- s = sbuf_new(NULL, NULL, 16, 0);
- SBUF_ASSERT_EQ(-1, sbuf_bcopyin(s, uptr, ulen));
- SBUF_ASSERT_EQ(0, s->s_len);
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("fail for kernel addresses")
- {
- struct sbuf *s = NULL;
- const void *uptr = "abcd";
- size_t ulen = 4;
-
- s = sbuf_new(NULL, NULL, 16, 0);
- SBUF_ASSERT_EQ(-1, sbuf_bcopyin(s, uptr, ulen));
- SBUF_ASSERT_EQ(0, s->s_len);
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("fail if we don't have capacity for a fixed-len sbuf")
- {
- struct sbuf *s = NULL;
- const void *uptr = (const void *)req->newptr;
- size_t ulen = req->newlen;
- int len_before;
-
- s = sbuf_new(NULL, NULL, 16, SBUF_FIXEDLEN);
- SBUF_ASSERT_EQ(0, sbuf_cpy(s, "0123456789abcde"));
- len_before = s->s_len;
- SBUF_ASSERT_EQ(-1, sbuf_bcopyin(s, uptr, ulen));
- SBUF_ASSERT_EQ(len_before, s->s_len);
- SBUF_ASSERT(SBUF_ISSET(s, SBUF_OVERFLOWED));
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("auto-extend if we don't have capacity for an auto-extend sbuf")
- {
- struct sbuf *s = NULL;
- const void *uptr = (const void *)req->newptr;
- size_t ulen = req->newlen;
- int len_before;
-
- s = sbuf_new(NULL, NULL, 16, SBUF_AUTOEXTEND);
- SBUF_ASSERT_EQ(0, sbuf_cpy(s, "0123456789abcde"));
- len_before = s->s_len;
- SBUF_ASSERT_EQ(0, sbuf_bcopyin(s, uptr, ulen));
- SBUF_ASSERT_EQ(len_before + (int)ulen, s->s_len);
- SBUF_ASSERT_NOT(SBUF_ISSET(s, SBUF_OVERFLOWED));
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("fail if overflowed")
- {
- struct sbuf *s = NULL;
- const void *uptr = (const void *)req->newptr;
- size_t ulen = req->newlen;
-
- s = sbuf_new(NULL, NULL, 16, 0);
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
- SBUF_ASSERT_EQ(-1, sbuf_bcopyin(s, uptr, ulen));
-
- sbuf_delete(s);
- }
- }
-
- SBUF_TESTING("sbuf_copyin")
- {
- SBUF_SHOULD("succeed in the simple case")
- {
- struct sbuf *s = NULL;
-
- s = sbuf_new(NULL, NULL, 16, SBUF_AUTOEXTEND);
- SBUF_ASSERT_EQ(req->newlen + 1, sbuf_copyin(s, (const void *)req->newptr, req->newlen));
- SBUF_ASSERT_EQ(req->newlen, s->s_len);
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("use the sbuf capacity if len is zero")
- {
- struct sbuf *s = NULL;
-
- s = sbuf_new(NULL, NULL, 16, SBUF_AUTOEXTEND);
- SBUF_ASSERT_EQ(req->newlen + 1, sbuf_copyin(s, (const void *)req->newptr, 0));
- SBUF_ASSERT_EQ(req->newlen, s->s_len);
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("fail if we can't extend the sbuf to accommodate")
- {
- struct sbuf *s = NULL;
-
- s = sbuf_new(NULL, NULL, 16, SBUF_FIXEDLEN);
- SBUF_ASSERT_EQ(0, sbuf_cpy(s, "0123456789abcde"));
- SBUF_ASSERT_EQ(-1, sbuf_copyin(s, (const void *)req->newptr, req->newlen));
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("auto-extend the buffer if necessary")
- {
- struct sbuf *s = NULL;
- int len_before;
-
- s = sbuf_new(NULL, NULL, 16, SBUF_AUTOEXTEND);
- SBUF_ASSERT_EQ(0, sbuf_cpy(s, "0123456789abcde"));
- len_before = s->s_len;
- SBUF_ASSERT_NE(-1, sbuf_copyin(s, (const void *)req->newptr, req->newlen));
- SBUF_ASSERT_GT(len_before, s->s_len);
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("fail if the sbuf is overflowed")
- {
- struct sbuf *s = NULL;
-
- s = sbuf_new(NULL, NULL, 16, SBUF_AUTOEXTEND);
- SBUF_SETFLAG(s, SBUF_OVERFLOWED);
- SBUF_ASSERT_EQ(-1, sbuf_copyin(s, (const void *)req->newptr, req->newlen));
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("fail gracefully for an invalid address")
- {
- struct sbuf *s = NULL;
-
- s = sbuf_new(NULL, NULL, 16, SBUF_AUTOEXTEND);
- SBUF_ASSERT_EQ(-1, sbuf_copyin(s, (void *)0xdeadUL, req->newlen));
-
- sbuf_delete(s);
- }
-
- SBUF_SHOULD("fail gracefully for a kernel address")
- {
- struct sbuf *s = NULL;
- const char *ptr = "abcd";
-
- s = sbuf_new(NULL, NULL, 16, SBUF_AUTOEXTEND);
- SBUF_ASSERT_EQ(-1, sbuf_copyin(s, ptr, strlen(ptr)));
-
- sbuf_delete(s);
- }
- }
-