TEST_F(HeapWalkerTest, live) { const int from_buffer_entries = 4; const int to_buffer_bytes = 16; for (int i = 0; i < from_buffer_entries; i++) { for (int j = 0; j < to_buffer_bytes; j++) { void* buffer1[from_buffer_entries]{}; char buffer2[to_buffer_bytes]{}; buffer1[i] = &buffer2[j]; HeapWalker heap_walker(heap_); heap_walker.Allocation(buffer_begin(buffer2), buffer_end(buffer2)); heap_walker.Root(buffer_begin(buffer1), buffer_end(buffer1)); ASSERT_EQ(true, heap_walker.DetectLeaks()); allocator::vector<Range> leaked(heap_); size_t num_leaks = SIZE_MAX; size_t leaked_bytes = SIZE_MAX; ASSERT_EQ(true, heap_walker.Leaked(leaked, 100, &num_leaks, &leaked_bytes)); EXPECT_EQ(0U, num_leaks); EXPECT_EQ(0U, leaked_bytes); EXPECT_EQ(0U, leaked.size()); } } }
TEST_F(HeapWalkerTest, unaligned) { const int from_buffer_entries = 4; const int to_buffer_bytes = 16; void* buffer1[from_buffer_entries]{}; char buffer2[to_buffer_bytes]{}; buffer1[1] = &buffer2; for (unsigned int i = 0; i < sizeof(uintptr_t); i++) { for (unsigned int j = 0; j < sizeof(uintptr_t); j++) { HeapWalker heap_walker(heap_); heap_walker.Allocation(buffer_begin(buffer2), buffer_end(buffer2)); heap_walker.Root(buffer_begin(buffer1) + i, buffer_end(buffer1) - j); ASSERT_EQ(true, heap_walker.DetectLeaks()); allocator::vector<Range> leaked(heap_); size_t num_leaks = SIZE_MAX; size_t leaked_bytes = SIZE_MAX; ASSERT_EQ(true, heap_walker.Leaked(leaked, 100, &num_leaks, &leaked_bytes)); EXPECT_EQ(0U, num_leaks); EXPECT_EQ(0U, leaked_bytes); EXPECT_EQ(0U, leaked.size()); } } }
void vncws_handshake_read(void *opaque) { VncState *vs = opaque; uint8_t *handshake_end; long ret; /* Typical HTTP headers from novnc are 512 bytes, so limiting * total header size to 4096 is easily enough. */ size_t want = 4096 - vs->ws_input.offset; buffer_reserve(&vs->ws_input, want); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want); if (!ret) { if (vs->csock == -1) { vnc_disconnect_finish(vs); } return; } vs->ws_input.offset += ret; handshake_end = (uint8_t *)g_strstr_len((char *)vs->ws_input.buffer, vs->ws_input.offset, WS_HANDSHAKE_END); if (handshake_end) { qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset); buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer + strlen(WS_HANDSHAKE_END)); } else if (vs->ws_input.offset >= 4096) { VNC_DEBUG("End of headers not found in first 4096 bytes\n"); vnc_client_error(vs); } }
static void text_term_client_read(void *opaque) { struct TextTermClientState *tcs = opaque; long ret; buffer_reserve(&tcs->input, 4096); ret = recv(tcs->csock, buffer_end(&tcs->input), 4096, 0); ret = text_term_client_io_error(tcs, ret, socket_error()); if (ret <= 0) return; tcs->input.offset += ret; while (tcs->input.offset > 0) { ssize_t ret = write(tcs->ts->ssock, tcs->input.buffer, tcs->input.offset); if (ret > 0) { if (ret != tcs->input.offset) { memmove(tcs->input.buffer, tcs->input.buffer + ret, tcs->input.offset - ret); } tcs->input.offset -= ret; } else { text_term_client_io_error(tcs, ret, socket_error()); return; } } }
int packet_fxp_realpath(Buffer *buff, Buffer *preped_buff) { u_int msg_len, xmsg_len; u_int file_len; u_char *filename; // Copy first part of packet over to prepared buffer msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; buffer_append(preped_buff, buffer_ptr(buff), 9); buffer_consume(buff, 9); xmsg_len -= 5; // Rewrite path filename = buffer_get_string(buff, &file_len); filename = unchroot_filename(filename, (u_char*) user_homedir); buffer_put_cstring(preped_buff, (char*) filename); xmsg_len -= (file_len + 4); msg_len += (strlen((char*) filename) - file_len); // Copy packet over to prepared buffer buffer_append(preped_buff, buffer_ptr(buff), xmsg_len); buffer_consume(buff, xmsg_len); // Replace length with new length put_u32(buffer_end(preped_buff)-msg_len-4, msg_len); return 1; }
int packet_fxp_mkdir(Buffer *buff, Buffer *preped_buff) { u_int msg_len; u_int xmsg_len; // File names u_int file_len; u_char *filename; // Copy first part of packet over to prepared buffer msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; buffer_append(preped_buff, buffer_ptr(buff), 9); buffer_consume(buff, 9); xmsg_len -= 5; // Rewrite path filename = buffer_get_string(buff, &file_len); filename = unchroot_filename(filename, (u_char*) user_homedir); buffer_put_cstring(preped_buff, (char*) filename); xmsg_len -= (file_len + 4); msg_len += (strlen((char*) filename) - file_len); // Copy attributes through, cleaning extensions where required parse_attrs(buff, preped_buff, &msg_len, &xmsg_len); // Copy any remaining packet data over buffer_append(preped_buff, buffer_ptr(buff), xmsg_len); buffer_consume(buff, xmsg_len); // Rewrite message length put_u32(buffer_end(preped_buff)-msg_len-4, msg_len); return 1; }
int packet_fxp_fsetstat(Buffer *buff, Buffer *preped_buff) { u_int msg_len; u_int xmsg_len; // File names u_int file_len; u_char *handle; // Copy first part of packet over to prepared buffer msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; buffer_append(preped_buff, buffer_ptr(buff), 9); buffer_consume(buff, 9); xmsg_len -= 5; // Copy handle handle = buffer_get_string(buff, &file_len); buffer_put_string(preped_buff, (char*) handle, file_len); xmsg_len -= (file_len + 4); // Copy attributes through, cleaning extensions where required parse_attrs(buff, preped_buff, &msg_len, &xmsg_len); // Copy any remaining packet data over buffer_append(preped_buff, buffer_ptr(buff), xmsg_len); buffer_consume(buff, xmsg_len); // Rewrite message length put_u32(buffer_end(preped_buff)-msg_len-4, msg_len); return 1; }
void vncws_handshake_read(void *opaque) { VncState *vs = opaque; uint8_t *handshake_end; long ret; buffer_reserve(&vs->ws_input, 4096); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); if (!ret) { if (vs->csock == -1) { vnc_disconnect_finish(vs); } return; } vs->ws_input.offset += ret; handshake_end = (uint8_t *)g_strstr_len((char *)vs->ws_input.buffer, vs->ws_input.offset, WS_HANDSHAKE_END); if (handshake_end) { qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset); buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer + strlen(WS_HANDSHAKE_END)); } }
long vnc_client_read_ws(VncState *vs) { int ret, err; uint8_t *payload; size_t payload_size, frame_size; VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer, vs->ws_input.capacity, vs->ws_input.offset); buffer_reserve(&vs->ws_input, 4096); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); if (!ret) { return 0; } vs->ws_input.offset += ret; /* make sure that nothing is left in the ws_input buffer */ do { err = vncws_decode_frame(&vs->ws_input, &payload, &payload_size, &frame_size); if (err <= 0) { return err; } buffer_reserve(&vs->input, payload_size); buffer_append(&vs->input, payload, payload_size); buffer_advance(&vs->ws_input, frame_size); } while (vs->ws_input.offset > 0); return ret; }
int main(int argc, char *argv[]) { enum timerec_type t = TIMEREC_SQLITE; enum timerec_action action = TIMEREC_NUMACTIONS; struct buffer *conn = NULL; struct timerec_data *tr; char *opt = NULL; int ret = EXIT_SUCCESS; size_t id = 0; if(read_args(argc, argv, &t, &conn, &action, &opt, &id) < 0) return EXIT_FAILURE; if(conn == NULL) default_dbpath(&conn); if(action == TIMEREC_NUMACTIONS) { usage(); goto error; } if(conn == NULL) return EXIT_FAILURE; if(timerec_init(t, buffer_cstr(conn), &tr) < 0) { ret = EXIT_FAILURE; goto error; } timerec_do(tr, action, opt, id); timerec_end(tr); error: buffer_end(conn); return ret; (void)argc; (void)argv; }
bool fix_field_unparse(struct fix_field *self, struct buffer *buffer) { buffer->end += uitoa(self->tag, buffer_end(buffer)); buffer_put(buffer, '='); switch (self->type) { case FIX_TYPE_STRING: { const char *p = self->string_value; while (*p) { buffer_put(buffer, *p++); } break; } case FIX_TYPE_STRING_8: { for (int i = 0; i < sizeof(self->string_8_value) && self->string_8_value[i]; ++i) { buffer_put(buffer, self->string_8_value[i]); } break; } case FIX_TYPE_CHAR: { buffer_put(buffer, self->char_value); break; } case FIX_TYPE_FLOAT: { // dtoa2 do not print leading zeros or .0, 7 digits needed sometimes buffer->end += modp_dtoa2(self->float_value, buffer_end(buffer), 7); break; } case FIX_TYPE_INT: { buffer->end += i64toa(self->int_value, buffer_end(buffer)); break; } case FIX_TYPE_CHECKSUM: { buffer->end += checksumtoa(self->int_value, buffer_end(buffer)); break; } default: break; }; buffer_put(buffer, 0x01); return true; }
yylex () { int c; buffer_init(); /* skip white spaces */ while (isspace((c = getchar()))) ; /* quotations ... */ if (c == '\'') return c; if (c == ')' || c=='(') return c; if (c == EOF) return 0; /* symbols or numbers */ if (!isspace(c) && c != '(' && c != ')') { int number_have_point = 0; int parse_as_symbol = 0; while (!isspace(c) && c != '(' && c != ')') { if (!parse_as_symbol) { if (c != '.' && !isdigit(c)) parse_as_symbol = 1; else if (c == '.') { if(number_have_point) parse_as_symbol = 1; number_have_point = 1; } } buffer_add(c); c = getchar(); } ungetc(c, stdin); yylval = buffer_end(); if (!strcmp(yylval, ".")) return SYMBOL; return parse_as_symbol ? SYMBOL : NUMBER; } fprintf(stderr, "%s : invalid input '%c' (%d). please email the author\n", program_name, c, c); exit(EXIT_FAILURE); }
//! assuming the packet has been properly initialized, //! this will fill bytes from @buffer into this packets buffer, //! then return the number of bytes written uint32_t fill(const std::string& buffer) { uint32_t rem = buffer_end() - data_end(); uint32_t total = (buffer.size() < rem) ? buffer.size() : rem; // copy from buffer to packet buffer memcpy(data_end(), buffer.data(), total); // set new packet length set_length(length() + total); return total; }
void process_input(void) { if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_SGA) && !HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO)) { read_key(); } else { read_line(); } if (!HAS_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT)) { return; } DEL_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT); if (gtd->chat && gtd->chat->paste_time) { chat_paste(gtd->input_buf, NULL); return; } if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO)) { add_line_history(gtd->ses, gtd->input_buf); } if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO)) { echo_command(gtd->ses, gtd->input_buf); } else { echo_command(gtd->ses, ""); } if (gtd->ses->scroll_line != -1) { buffer_end(gtd->ses, ""); } check_all_events(gtd->ses, SUB_ARG|SUB_SEC, 0, 1, "RECEIVED INPUT", gtd->input_buf); gtd->ses = script_driver(gtd->ses, LIST_COMMAND, gtd->input_buf); if (IS_SPLIT(gtd->ses)) { erase_toeol(); } gtd->input_buf[0] = 0; }
void default_dbpath(struct buffer **b) { char *e = getenv("HOME"); if(e == NULL) return; *b = buffer_new(256); if(*b == NULL) return; if(util_stripjoin(b, OS_DIRECTORY_SEP, e, ".timerec.dat", NULL) < 0) { buffer_end(*b); *b = NULL; } }
TEST_F(HeapWalkerTest, cycle) { void* buffer1; void* buffer2; buffer1 = &buffer2; buffer2 = &buffer1; HeapWalker heap_walker(heap_); heap_walker.Allocation(buffer_begin(buffer1), buffer_end(buffer1)); heap_walker.Allocation(buffer_begin(buffer2), buffer_end(buffer2)); ASSERT_EQ(true, heap_walker.DetectLeaks()); allocator::vector<Range> leaked(heap_); size_t num_leaks = 0; size_t leaked_bytes = 0; ASSERT_EQ(true, heap_walker.Leaked(leaked, 100, &num_leaks, &leaked_bytes)); EXPECT_EQ(2U, num_leaks); EXPECT_EQ(2*sizeof(uintptr_t), leaked_bytes); ASSERT_EQ(2U, leaked.size()); }
TEST_F(HeapWalkerTest, leak) { void* buffer1[16]{}; char buffer2[16]{}; buffer1[0] = &buffer2[0] - sizeof(void*); buffer1[1] = &buffer2[15] + sizeof(void*); HeapWalker heap_walker(heap_); heap_walker.Allocation(buffer_begin(buffer2), buffer_end(buffer2)); ASSERT_EQ(true, heap_walker.DetectLeaks()); allocator::vector<Range> leaked(heap_); size_t num_leaks = 0; size_t leaked_bytes = 0; ASSERT_EQ(true, heap_walker.Leaked(leaked, 100, &num_leaks, &leaked_bytes)); EXPECT_EQ(1U, num_leaks); EXPECT_EQ(16U, leaked_bytes); ASSERT_EQ(1U, leaked.size()); EXPECT_EQ(buffer_begin(buffer2), leaked[0].begin); EXPECT_EQ(buffer_end(buffer2), leaked[0].end); }
long vnc_client_read_ws(VncState *vs) { int ret, err; uint8_t *payload; size_t payload_size, header_size; VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer, vs->ws_input.capacity, vs->ws_input.offset); buffer_reserve(&vs->ws_input, 4096); ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); if (!ret) { return 0; } vs->ws_input.offset += ret; ret = 0; /* consume as much of ws_input buffer as possible */ do { if (vs->ws_payload_remain == 0) { err = vncws_decode_frame_header(&vs->ws_input, &header_size, &vs->ws_payload_remain, &vs->ws_payload_mask); if (err <= 0) { return err; } buffer_advance(&vs->ws_input, header_size); } if (vs->ws_payload_remain != 0) { err = vncws_decode_frame_payload(&vs->ws_input, &vs->ws_payload_remain, &vs->ws_payload_mask, &payload, &payload_size); if (err < 0) { return err; } if (err == 0) { return ret; } ret += err; buffer_reserve(&vs->input, payload_size); buffer_append(&vs->input, payload, payload_size); buffer_advance(&vs->ws_input, payload_size); } } while (vs->ws_input.offset > 0); return ret; }
int packet_read_query_section(buffer_type *packet, uint8_t* dst, uint16_t* qtype, uint16_t* qclass) { uint8_t *query_name = buffer_current(packet); uint8_t *src = query_name; size_t len; while (*src) { /* * If we are out of buffer limits or we have a pointer * in question dname or the domain name is longer than * MAXDOMAINLEN ... */ if ((*src & 0xc0) || (src + *src + 2 > buffer_end(packet)) || (src + *src + 2 > query_name + MAXDOMAINLEN)) { return 0; } memcpy(dst, src, *src + 1); dst += *src + 1; src += *src + 1; } *dst++ = *src++; /* Make sure name is not too long or we have stripped packet... */ len = src - query_name; if (len > MAXDOMAINLEN || (src + 2*sizeof(uint16_t) > buffer_end(packet))) { return 0; } buffer_set_position(packet, src - buffer_begin(packet)); *qtype = buffer_read_u16(packet); *qclass = buffer_read_u16(packet); return 1; }
ssize_t buffer_xread(struct buffer *buf, int fd) { size_t count; ssize_t len; void *end; end = buffer_end(buf); count = buffer_remaining(buf); len = xread(fd, end, count); if (len < 0) return len; buf->end += len; return len; }
ssize_t buffer_recv(struct buffer *buf, int sockfd, size_t size, int flags) { size_t count; ssize_t len; void *end; end = buffer_end(buf); count = buffer_remaining(buf); if (count > size) count = size; len = io_recv(sockfd, end, count, flags); if (len < 0) return len; buf->end += len; return len; }
static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc, Error **errp) { char *handshake_end; ssize_t ret; /* Typical HTTP headers from novnc are 512 bytes, so limiting * total header size to 4096 is easily enough. */ size_t want = 4096 - ioc->encinput.offset; buffer_reserve(&ioc->encinput, want); ret = qio_channel_read(ioc->master, (char *)buffer_end(&ioc->encinput), want, errp); if (ret < 0) { return -1; } ioc->encinput.offset += ret; handshake_end = g_strstr_len((char *)ioc->encinput.buffer, ioc->encinput.offset, QIO_CHANNEL_WEBSOCK_HANDSHAKE_END); if (!handshake_end) { if (ioc->encinput.offset >= 4096) { error_setg(errp, "End of headers not found in first 4096 bytes"); return -1; } else { return 0; } } if (qio_channel_websock_handshake_process(ioc, (char *)ioc->encinput.buffer, ioc->encinput.offset, errp) < 0) { return -1; } buffer_advance(&ioc->encinput, handshake_end - (char *)ioc->encinput.buffer + strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_END)); return 1; }
bool buffer_printf(struct buffer *buf, const char *format, ...) { size_t size; va_list ap; char *end; int len; end = buffer_end(buf); size = buffer_remaining(buf); va_start(ap, format); len = vsnprintf(end, size, format, ap); va_end(ap); if (len < 0 || len >= size) return false; buf->end += len; return true; }
ssize_t buffer_inflate(struct buffer *comp_buf, struct buffer *uncomp_buf, z_stream *stream) { unsigned long nr; ssize_t ret; int err; nr = buffer_size(comp_buf); if (!nr) return 0; if (nr > INFLATE_SIZE) nr = INFLATE_SIZE; stream->avail_in = nr; stream->avail_out = buffer_remaining(uncomp_buf); stream->next_out = (void *) buffer_end(uncomp_buf); retry: err = inflate(stream, Z_NO_FLUSH); switch (err) { case Z_STREAM_END: case Z_BUF_ERROR: case Z_OK: /* OK to continue */ break; default: return -1; } if (!err && !stream->avail_out) goto retry; buffer_advance(comp_buf, nr - stream->avail_in); ret = buffer_remaining(uncomp_buf) - stream->avail_out; uncomp_buf->end += ret; return ret; }
int packet_fxp_symlink(Buffer *buff, Buffer *preped_buff) { u_int msg_len; u_int xmsg_len; // File names u_int file_len; u_char *filename; // Copy first part of packet over to prepared buffer msg_len = get_u32(buffer_ptr(buff)); xmsg_len = msg_len; buffer_append(preped_buff, buffer_ptr(buff), 9); buffer_consume(buff, 9); xmsg_len -= 5; // Rewrite link path filename = buffer_get_string(buff, &file_len); filename = unchroot_filename(filename, (u_char*) user_homedir); buffer_put_cstring(preped_buff, (char*) filename); xmsg_len -= (file_len + 4); msg_len += (strlen((char*) filename) - file_len); // Rewrite target path filename = buffer_get_string(buff, &file_len); filename = unchroot_filename(filename, (u_char*) user_homedir); buffer_put_cstring(preped_buff, (char*) filename); xmsg_len -= (file_len + 4); msg_len += (strlen((char*) filename) - file_len); // Copy any remaining packet data over buffer_append(preped_buff, buffer_ptr(buff), xmsg_len); buffer_consume(buff, xmsg_len); // Rewrite message length put_u32(buffer_end(preped_buff)-msg_len-4, msg_len); return 1; }
transition_result_t handle_data(context_t *context) { buffer_t *in_buf = &context->in_message; if (context->is_wait_transition) { switch (transaction_add_data_status(&context->transaction)) { case TRANSACTION_DONE: if (buffer_space(&context->in_message) == 0) { buffer_drop_read(&context->in_message); } context->is_wait_transition = 0; return TRANSITION_SUCCEED; case TRANSACTION_WAIT: return TRANSITION_WAIT; default: return TRANSITION_ERROR; } } const char *begin = buffer_find(in_buf, CRLF, sizeof(CRLF) - 1); if (begin == buffer_end(in_buf)) { return TRANSITION_ERROR; } const char *data = buffer_read_begin(in_buf); const size_t data_size = begin - data + sizeof(CRLF) - 1; if (transaction_add_data(&context->transaction, data, data_size) != data_size) { return TRANSITION_ERROR; } buffer_shift_read(in_buf, data_size); context->is_wait_transition = 1; return TRANSITION_WAIT; }
static int start_commit_buffered_syscall(int syscallno, void* record_end, int blockness) { void* record_start; void* stored_end; struct syscallbuf_record* rec; if (!buffer) { return 0; } record_start = buffer_last(); stored_end = record_start + stored_record_size(record_end - record_start); rec = record_start; if (stored_end < record_start + sizeof(struct syscallbuf_record)) { /* Either a catastrophic buffer overflow or * we failed to lock the buffer. Just bail out. */ return 0; } if (stored_end > (void*)buffer_end() - sizeof(struct syscallbuf_record)) { /* Buffer overflow. * Unlock the buffer and then execute the system call * with a trap to rr. Note that we reserve enough * space in the buffer for the next prep_syscall(). */ buffer_hdr()->locked = 0; return 0; } /* Store this breadcrumb so that the tracer can find out what * syscall we're executing if our registers are in a weird * state. If we end up aborting this syscall, no worry, this * will just be overwritten later. * * NBB: this *MUST* be set before the desched event is * armed. */ rec->syscallno = syscallno; rec->desched = MAY_BLOCK == blockness; rec->size = record_end - record_start; if (rec->desched) { /* NB: the ordering of the next two statements is * important. * * We set this flag to notify rr that it should pay * attention to desched signals pending for this task. * We have to set it *before* we arm the notification * because we can't set the flag atomically with * arming the event (too bad there's no ioctl() for * querying the event enabled-ness state). That's * important because if the notification is armed, * then rr must be confident that when it disarms the * event, the tracee is at an execution point that * *must not* need the desched event. * * If we were to set the flag non-atomically after the * event was armed, then if a desched signal was * delivered right at the instruction that set the * flag, rr wouldn't know that it needed to advance * the tracee to the untraced syscall entry point. * (And if rr didn't do /that/, then the syscall might * block without rr knowing it, and the recording * session would deadlock.) */ buffer_hdr()->desched_signal_may_be_relevant = 1; arm_desched_event(); } return 1; }