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());
    }
  }
}
Пример #3
0
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);
    }
}
Пример #4
0
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;
        }
    }
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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));
    }
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
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);
}
Пример #13
0
 //! 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;
 }
Пример #14
0
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;
}
Пример #15
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);
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
0
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;
}
Пример #21
0
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;
}
Пример #22
0
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;
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
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;
}
Пример #26
0
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;
}
Пример #27
0
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;
}