Пример #1
0
static VALUE
string_to_c_strict(VALUE self)
{
    char *s;
    VALUE num;

    rb_must_asciicompat(self);

    s = RSTRING_PTR(self);

    if (!s || memchr(s, '\0', RSTRING_LEN(self)))
	rb_raise(rb_eArgError, "string contains null byte");

    if (s && s[RSTRING_LEN(self)]) {
	rb_str_modify(self);
	s = RSTRING_PTR(self);
	s[RSTRING_LEN(self)] = '\0';
    }

    if (!s)
	s = (char *)"";

    if (!parse_comp(s, 1, &num)) {
	rb_raise(rb_eArgError, "invalid value for convert(): %+"PRIsVALUE,
		 self);
    }

    return num;
}
Пример #2
0
VALUE
rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
{
    rb_printf_buffer_extra buffer;
#define f buffer.base
    VALUE klass;

    StringValue(str);
    rb_str_modify(str);
    f._flags = __SWR | __SSTR;
    f._bf._size = 0;
    f._w = rb_str_capacity(str);
    f._bf._base = (unsigned char *)str;
    f._p = (unsigned char *)RSTRING_END(str);
    klass = RBASIC(str)->klass;
    RBASIC_CLEAR_CLASS(str);
    f.vwrite = ruby__sfvwrite;
    f.vextra = ruby__sfvextra;
    buffer.value = 0;
    BSD_vfprintf(&f, fmt, ap);
    RBASIC_SET_CLASS_RAW(str, klass);
    rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
#undef f

    return str;
}
Пример #3
0
static VALUE
bug_str_qsort_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE beg, len, size;
    long l, b = 0, n, s = 1;
    struct sort_data d;

    rb_scan_args(argc, argv, "03", &beg, &len, &size);
    l = RSTRING_LEN(str);
    if (!NIL_P(beg) && (b = NUM2INT(beg)) < 0 && (b += l) < 0) {
	rb_raise(rb_eArgError, "out of bounds");
    }
    if (!NIL_P(size) && (s = NUM2INT(size)) < 0) {
	rb_raise(rb_eArgError, "negative size");
    }
    if (NIL_P(len) ||
	(((n = NUM2INT(len)) < 0) ?
	 (rb_raise(rb_eArgError, "negative length"), 0) :
	 (b + n * s > l))) {
	n = (l - b) / s;
    }
    rb_str_modify(str);
    d.enc = rb_enc_get(str);
    d.elsize = s;
    ruby_qsort(RSTRING_PTR(str) + b, n, s,
	       rb_block_given_p() ? cmp_1 : cmp_2, &d);
    return str;
}
Пример #4
0
VALUE
rb_str_clear( VALUE str)
{
    rb_str_modify( str);
    rb_str_resize( str, 0);
    return str;
}
Пример #5
0
/* USB::DevHandle#usb_control_msg(requesttype, request, value, index, bytes, timeout) */
static VALUE
rusb_control_msg(
  VALUE v,
  VALUE vrequesttype,
  VALUE vrequest,
  VALUE vvalue,
  VALUE vindex,
  VALUE vbytes,
  VALUE vtimeout)
{
  usb_dev_handle *p = get_usb_devhandle(v);
  int requesttype = NUM2INT(vrequesttype);
  int request = NUM2INT(vrequest);
  int value = NUM2INT(vvalue);
  int index = NUM2INT(vindex);
  int timeout = NUM2INT(vtimeout);
  char *bytes;
  int size;
  int ret;
  StringValue(vbytes);
  rb_str_modify(vbytes);
  bytes = RSTRING_PTR(vbytes);
  size = RSTRING_LEN(vbytes);
  ret = usb_control_msg(p, requesttype, request, value, index, bytes, size, timeout);
  check_usb_error("usb_control_msg", ret);
  return INT2NUM(ret);
}
Пример #6
0
static VALUE
rb_utf_chomp_default(VALUE str)
{
        rb_str_modify(str);

        const char *end = RSTRING(str)->ptr + RSTRING(str)->len;

        char *last = utf_find_prev(RSTRING(str)->ptr, end);
        if (last == NULL)
                return Qnil;

        if (_utf_char_validated(last, end) == '\n') {
                char *last_but_one = utf_find_prev(RSTRING(str)->ptr, last);

                if (last_but_one != NULL && utf_char(last_but_one) == '\r')
                        last = last_but_one;
        } else if (!unichar_isnewline(utf_char(last))) {
                return Qnil;
        }

        RSTRING(str)->len -= (RSTRING(str)->ptr + RSTRING(str)->len) - last;
        *last = '\0';

        return str;
}
Пример #7
0
static int read_check(struct io_args *a, long n, const char *msg, int io_wait)
{
	if (n == -1) {
		if (errno == EINTR) {
			a->fd = my_fileno(a->io);
			return -1;
		}
		rb_str_set_len(a->buf, 0);
		if (errno == EAGAIN) {
			if (io_wait) {
				(void)kgio_call_wait_readable(a->io);

				/* buf may be modified in other thread/fiber */
				rb_str_modify(a->buf);
				rb_str_resize(a->buf, a->len);
				a->ptr = RSTRING_PTR(a->buf);
				return -1;
			} else {
				a->buf = sym_wait_readable;
				return 0;
			}
		}
		rd_sys_fail(msg);
	}
	rb_str_set_len(a->buf, n);
	if (n == 0)
		a->buf = Qnil;
	return 0;
}
Пример #8
0
VALUE
rb_str_cut_bang( VALUE str, VALUE len)
{
    int l;
#ifdef HAVE_HEADER_RUBY_H
#else
    int n;
#endif

    rb_str_modify( str);
    l = NUM2INT( len);
    if (l < 0)
        l = 0;
#ifdef HAVE_HEADER_RUBY_H
    if (l < RSTRING_LEN( str)) {
        RSTRING_LEN( str) = l;
        return str;
    }
#else
    n = rb_str_strlen( str);
    if (l < n) {
        rb_str_update( str, l, n - l, rb_str_new( NULL, 0));
        return str;
    }
#endif
    return Qnil;
}
Пример #9
0
/*
 * call-seq:
 *    ssl.sysread(length) => string
 *    ssl.sysread(length, buffer) => buffer
 *
 * === Parameters
 * * +length+ is a positive integer.
 * * +buffer+ is a string used to store the result.
 */
static VALUE
ossl_ssl_read(int argc, VALUE *argv, VALUE self)
{
  SSL *ssl;
  int ilen, nread = 0;
  VALUE len, str;

  rb_scan_args(argc, argv, "11", &len, &str);
  ilen = NUM2INT(len);

  if(NIL_P(str)) {
    str = rb_str_new(0, ilen);
  } else {
    StringValue(str);
    rb_str_modify(str);
    rb_str_resize(str, ilen);
  }

  if(ilen == 0) return str;

  Data_Get_Struct(self, SSL, ssl);
  int fd = rb_io_fd(ossl_ssl_get_io(self));

  if (ssl) {
    if(SSL_pending(ssl) <= 0)
      rb_thread_wait_fd(fd);
    for (;;) {
      nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LEN(str));
      switch(ssl_get_error(ssl, nread)) {
      case SSL_ERROR_NONE:
        goto end;
      case SSL_ERROR_ZERO_RETURN:
        rb_eof_error();
      case SSL_ERROR_WANT_WRITE:
        rb_io_wait_writable(fd);
        continue;
      case SSL_ERROR_WANT_READ:
        rb_io_wait_readable(fd);
        continue;
      case SSL_ERROR_SYSCALL:
        if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
        rb_sys_fail(0);
      default:
        ossl_raise(eSSLError, "SSL_read:");
      }
    }
  }
  else {
    ID id_sysread = rb_intern("sysread");
    rb_warning("SSL session is not started yet.");
    return rb_funcall(ossl_ssl_get_io(self), id_sysread, 2, len, str);
  }

end:
  rb_str_set_len(str, nread);
  OBJ_TAINT(str);

  return str;
}
Пример #10
0
static VALUE
bug_str_cstr_unterm(VALUE str, VALUE c)
{
    long len;

    rb_str_modify(str);
    len = RSTRING_LEN(str);
    RSTRING_PTR(str)[len] = NUM2CHR(c);
    return str;
}
static VALUE
pg_tmir_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx )
{
	t_tmir *this = (t_tmir *) p_typemap;
	rb_encoding *p_encoding = rb_enc_from_index(enc_idx);
	VALUE enc = rb_enc_from_encoding(p_encoding);
	/* field_str is reused in-place by pg_text_dec_copy_row(), so we need to make
	 * a copy of the string buffer for use in ruby space. */
	VALUE field_str_copy = rb_str_dup(field_str);
	rb_str_modify(field_str_copy);

	return rb_funcall( this->self, s_id_typecast_copy_get, 4, field_str_copy, INT2NUM(fieldno), INT2NUM(format), enc );
}
Пример #12
0
VALUE
rb_str_eat( int argc, VALUE *argv, VALUE str)
{
    VALUE val;
    int n;
    int l;
    int r;

#ifdef HAVE_HEADER_RUBY_H
    n = l = RSTRING_LEN( str);
#else
    n = l = rb_str_strlen( str);
#endif
    if (rb_scan_args( argc, argv, "01", &val) == 1) {
        if (!NIL_P( val)) {
            int v = NUM2INT( val);
            if (v >= 0) {
                if (n >= v) n = v;
            } else {
                n = -n;
                if (n <= v) n = v;
            }
        }
    }
    rb_str_modify( str);
#ifdef HAVE_HEADER_RUBY_H
    if (n > 0) {
        r = l - n;
        val = rb_str_new5( str, RSTRING_PTR( str), n);
        memmove( RSTRING_PTR( str), RSTRING_PTR( str) + n, r);
    } else {
        r = l + n;
        val = rb_str_new5( str, RSTRING_PTR( str) + r, -n);
    }
    RSTRING_LEN( str) = r;
    OBJ_INFECT( val, str);
#else
    if (n > 0) {
        r = 0;
    } else if (n < 0) {
        r = l + n;
        n = -n;
    } else
        return Qnil;
    val = rb_str_substr( str, r, n);
    if (!NIL_P(val))
        rb_str_update( str, r, n, rb_str_new( NULL, 0));
#endif
    return val;
}
Пример #13
0
VALUE string_xor( int argc, VALUE *argv, VALUE self ) {
  const char *src = 0;
  const char *src2 = 0;
  char *dest = 0 ;
  size_t length = 0;
  size_t l;

  if ( (argc < 1) || (argc > 2) ) {
    rb_raise( rb_eArgError, "wrong # of arguments(%d for 1 or 2)", argc );
    return Qnil;
  }

  rb_str_modify(self);
  dest = RSTRING_PTR(self);
  length = RSTRING_LEN(self);

  if ( TYPE(argv[0]) == T_STRING ) {
    l = RSTRING_LEN(argv[0]);
    src = RSTRING_PTR(argv[0]);
    if ( l < length )
      length = l;
  } else {
    rb_raise( rb_eTypeError, "in method '" "xor" "', argument " "1"" of type '" "String""'" );
    return Qnil;
  }

  if ( argc == 1 ) {
    for ( ; length--; ++dest, ++src )
      *dest ^= *src;

  } else {
    if ( TYPE(argv[1]) == T_STRING ) {
      l = RSTRING_LEN(argv[1]);
      src2 = RSTRING_PTR(argv[1]);
      if ( l < length )
        length = l;
    } else {
      rb_raise( rb_eTypeError, "in method '" "xor" "', argument " "2"" of type '" "String""'" );
      return Qnil;
    }

    for ( ; length--; ++dest, ++src, ++src2 )
      *dest ^= *src ^ *src2;
  }

  return self;
}
Пример #14
0
static void prepare_read(struct io_args *a, int argc, VALUE *argv, VALUE io)
{
	VALUE length;

	a->io = io;
	a->fd = my_fileno(io);
	rb_scan_args(argc, argv, "11", &length, &a->buf);
	a->len = NUM2LONG(length);
	if (NIL_P(a->buf)) {
		a->buf = rb_str_new(NULL, a->len);
	} else {
		StringValue(a->buf);
		rb_str_modify(a->buf);
		rb_str_resize(a->buf, a->len);
	}
	a->ptr = RSTRING_PTR(a->buf);
}
Пример #15
0
/**
 * Set four bytes for int32 in a binary string and return it.
 *
 * @example Set int32 in a BSON string.
 *   rb_string_set_int32(self, pos, int32)
 *
 * @param [ String ] self The Ruby binary string.
 * @param [ Fixnum ] The position to set.
 * @param [ Fixnum ] The int32 value.
 *
 * @return [ String ] The binary string.
 *
 * @since 2.0.0
 */
static VALUE rb_string_set_int32(VALUE str, VALUE pos, VALUE an_int32)
{
  const int32_t offset = NUM2INT(pos);
  const int32_t v = NUM2INT(an_int32);
  const char bytes[4] = {
    v & 255,
    (v >> 8) & 255,
    (v >> 16) & 255,
    (v >> 24) & 255
  };
  rb_str_modify(str);
  if (offset < 0 || offset + 4 > RSTRING_LEN(str)) {
    rb_raise(rb_eArgError, "invalid position");
  }
  memcpy(RSTRING_PTR(str) + offset, bytes, 4);
  return str;
}
Пример #16
0
VALUE
rb_utf_chomp_bang(int argc, VALUE *argv, UNUSED(VALUE self))
{
        VALUE str, rs;

        rb_scan_args(argc, argv, "11", &str, &rs);

        if (RSTRING(str)->len == 0)
                return Qnil;

        if (argc == 1) {
                rs = rb_rs;
                if (rs == rb_default_rs)
                        rb_utf_chomp_default(str);
        }

        if (NIL_P(rs))
                return Qnil;

        StringValue(rs);

        long rs_len = RSTRING(rs)->len;
        if (rs_len == 0)
                return rb_utf_chomp_newlines(str);

        long len = RSTRING(str)->len;
        if (rs_len > len)
                return Qnil;

        char last_char = RSTRING(rs)->ptr[rs_len - 1];
        if (rs_len == 1 && last_char == '\n')
                rb_utf_chomp_default(str);

        char *p = RSTRING(str)->ptr;

        if (p[len - 1] != last_char ||
            (rs_len > 1 &&
             rb_memcmp(RSTRING(rs)->ptr, p + len - rs_len, rs_len) != 0))
                return Qnil;

        rb_str_modify(str);
        RSTRING(str)->len -= rs_len;
        RSTRING(str)->ptr[RSTRING(str)->len] = '\0';

        return str;
}
Пример #17
0
/* USB::DevHandle#usb_get_string_simple(index, buf) */
static VALUE
rusb_get_string_simple(
  VALUE v,
  VALUE vindex,
  VALUE vbuf)
{
  usb_dev_handle *p = get_usb_devhandle(v);
  int index = NUM2INT(vindex);
  char *buf;
  int buflen;
  int ret;
  StringValue(vbuf);
  rb_str_modify(vbuf);
  buf = RSTRING_PTR(vbuf);
  buflen = RSTRING_LEN(vbuf);
  ret = usb_get_string_simple(p, index, buf, buflen);
  check_usb_error("usb_get_string_simple", ret);
  return INT2NUM(ret);
}
Пример #18
0
/* USB::DevHandle#usb_get_driver_np(interface, name) */
static VALUE
rusb_get_driver_np(
  VALUE v,
  VALUE vinterface,
  VALUE vname)
{
  usb_dev_handle *p = get_usb_devhandle(v);
  int interface = NUM2INT(vinterface);
  char *name;
  int namelen;
  int ret;
  StringValue(vname);
  rb_str_modify(vname);
  name = RSTRING_PTR(vname);
  namelen = RSTRING_LEN(vname);
  ret = usb_get_driver_np(p, interface, name, namelen);
  check_usb_error("usb_get_driver_np", ret);
  return Qnil;
}
Пример #19
0
static VALUE _receive(int rflags, int argc, VALUE *argv, VALUE self)
{
	struct posix_mq *mq = get(self, 1);
	struct rw_args x;
	VALUE buffer, timeout;
	struct timespec expire;

	if (mq->attr.mq_msgsize < 0) {
		if (mq_getattr(mq->des, &mq->attr) < 0)
			rb_sys_fail("mq_getattr");
	}

	rb_scan_args(argc, argv, "02", &buffer, &timeout);
	x.timeout = convert_timeout(&expire, timeout);

	if (NIL_P(buffer)) {
		buffer = rb_str_new(0, mq->attr.mq_msgsize);
	} else {
		StringValue(buffer);
		rb_str_modify(buffer);
		rb_str_resize(buffer, mq->attr.mq_msgsize);
	}
	OBJ_TAINT(buffer);
	x.msg_ptr = RSTRING_PTR(buffer);
	x.msg_len = (size_t)mq->attr.mq_msgsize;
	x.des = mq->des;

retry:
	WITHOUT_GVL(xrecv, &x, RUBY_UBF_IO, 0);
	if (x.received < 0) {
		if (errno == EINTR)
			goto retry;
		if (errno == EAGAIN && (rflags & PMQ_TRY))
			return Qnil;
		rb_sys_fail("mq_receive");
	}

	rb_str_set_len(buffer, x.received);

	if (rflags & PMQ_WANTARRAY)
		return rb_ary_new3(2, buffer, UINT2NUM(x.msg_prio));
	return buffer;
}
Пример #20
0
/* USB::DevHandle#usb_interrupt_read(endpoint, bytes, timeout) */
static VALUE
rusb_interrupt_read(
  VALUE v,
  VALUE vep,
  VALUE vbytes,
  VALUE vtimeout)
{
  usb_dev_handle *p = get_usb_devhandle(v);
  int ep = NUM2INT(vep);
  int timeout = NUM2INT(vtimeout);
  char *bytes;
  int size;
  int ret;
  StringValue(vbytes);
  rb_str_modify(vbytes);
  bytes = RSTRING_PTR(vbytes);
  size = RSTRING_LEN(vbytes);
  ret = usb_interrupt_read(p, ep, bytes, size, timeout);
  check_usb_error("usb_interrupt_read", ret);
  return INT2NUM(ret);
}
Пример #21
0
VALUE
rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
{
    rb_printf_buffer f;
    VALUE klass;

    StringValue(str);
    rb_str_modify(str);
    f._flags = __SWR | __SSTR;
    f._bf._size = 0;
    f._w = rb_str_capacity(str);
    f._bf._base = (unsigned char *)str;
    f._p = (unsigned char *)RSTRING_END(str);
    klass = RBASIC(str)->klass;
    RBASIC(str)->klass = 0;
    f.vwrite = ruby__sfvwrite;
    BSD_vfprintf(&f, fmt, ap);
    RBASIC(str)->klass = klass;
    rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));

    return str;
}
Пример #22
0
/* USB::DevHandle#usb_get_descriptor_by_endpoint(endpoint, type, index, buf) */
static VALUE
rusb_get_descriptor_by_endpoint(
  VALUE v,
  VALUE vep,
  VALUE vtype,
  VALUE vindex,
  VALUE vbuf)
{
  usb_dev_handle *p = get_usb_devhandle(v);
  int ep = NUM2INT(vep);
  int type = NUM2INT(vtype);
  int index = NUM2INT(vindex);
  char *buf;
  int buflen;
  int ret;
  StringValue(vbuf);
  rb_str_modify(vbuf);
  buf = RSTRING_PTR(vbuf);
  buflen = RSTRING_LEN(vbuf);
  ret = usb_get_descriptor_by_endpoint(p, ep, type, index, buf, buflen);
  check_usb_error("usb_get_descriptor_by_endpoint", ret);
  return INT2NUM(ret);
}
Пример #23
0
/*
 * call-seq:
 *    str.to_c  ->  complex
 *
 * Returns a complex which denotes the string form.  The parser
 * ignores leading whitespaces and trailing garbage.  Any digit
 * sequences can be separated by an underscore.  Returns zero for null
 * or garbage string.
 *
 *    '9'.to_c           #=> (9+0i)
 *    '2.5'.to_c         #=> (2.5+0i)
 *    '2.5/1'.to_c       #=> ((5/2)+0i)
 *    '-3/2'.to_c        #=> ((-3/2)+0i)
 *    '-i'.to_c          #=> (0-1i)
 *    '45i'.to_c         #=> (0+45i)
 *    '3-4i'.to_c        #=> (3-4i)
 *    '-4e2-4e-2i'.to_c  #=> (-400.0-0.04i)
 *    '-0.0-0.0i'.to_c   #=> (-0.0-0.0i)
 *    '1/2+3/4i'.to_c    #=> ((1/2)+(3/4)*i)
 *    'ruby'.to_c        #=> (0+0i)
 *
 * See Kernel.Complex.
 */
static VALUE
string_to_c(VALUE self)
{
    char *s;
    VALUE num;

    rb_must_asciicompat(self);

    s = RSTRING_PTR(self);

    if (s && s[RSTRING_LEN(self)]) {
	rb_str_modify(self);
	s = RSTRING_PTR(self);
	s[RSTRING_LEN(self)] = '\0';
    }

    if (!s)
	s = (char *)"";

    (void)parse_comp(s, 0, &num);

    return num;
}
Пример #24
0
static VALUE
rb_utf_chomp_newlines(VALUE str)
{
        char *begin = RSTRING(str)->ptr;
        char *end = begin + RSTRING(str)->len;

        char *last = end;
        while (last > begin) {
                char *last_but_one = utf_find_prev(begin, last);
                if (last == NULL || !unichar_isnewline(utf_char(last_but_one)))
                        break;
                last = last_but_one;
        }

        if (last == end)
                return Qnil;

        rb_str_modify(str);
        RSTRING(str)->len -= end - last;
        *last = '\0';

        return str;
}
Пример #25
0
static VALUE
ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
{
    SSL *ssl;
    int ilen, nread = 0;
    VALUE len, str;
    rb_io_t *fptr;

    rb_scan_args(argc, argv, "11", &len, &str);
    ilen = NUM2INT(len);
    if(NIL_P(str)) {
	str = rb_bstr_new();
    }
    else{
        StringValue(str);
	rb_str_modify(str);
	str = rb_str_bstr(str);
    }
    rb_bstr_resize(str, ilen);
    if(ilen == 0) return str;

    Data_Get_Struct(self, SSL, ssl);
    GetOpenFile(ossl_ssl_get_io(self), fptr);
    if (ssl) {
	if(!nonblock && SSL_pending(ssl) <= 0)
	    rb_thread_wait_fd(FPTR_TO_FD(fptr));
	for (;;){
	    nread = SSL_read(ssl, rb_bstr_bytes(str),
		    rb_bstr_length(str));
	    switch(ssl_get_error(ssl, nread)){
	    case SSL_ERROR_NONE:
		goto end;
	    case SSL_ERROR_ZERO_RETURN:
		rb_eof_error();
	    case SSL_ERROR_WANT_WRITE:
                write_would_block(nonblock);
                rb_io_wait_writable(FPTR_TO_FD(fptr));
                continue;
	    case SSL_ERROR_WANT_READ:
                read_would_block(nonblock);
                rb_io_wait_readable(FPTR_TO_FD(fptr));
		continue;
	    case SSL_ERROR_SYSCALL:
		if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
		rb_sys_fail(0);
	    default:
		ossl_raise(eSSLError, "SSL_read:");
	    }
        }
    }
    else {
        ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
        rb_warning("SSL session is not started yet.");
        return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str);
    }

  end:
    rb_bstr_resize(str, nread);
    OBJ_TAINT(str);

    return str;
}
Пример #26
0
VALUE image_open(VALUE self, VALUE filename_location, VALUE disk_type_flag) {
  char * filename; int dtype;
  struct tsk4r_img_wrapper * ptr;
  Data_Get_Struct(self, struct tsk4r_img_wrapper, ptr);
  
  VALUE img_size;
  VALUE img_sector_size;
  VALUE description = Qnil; VALUE name = Qnil;
  dtype = FIX2ULONG(disk_type_flag);
  TSK_IMG_TYPE_ENUM * type_flag_num = get_img_flag(disk_type_flag);
  
  if (rb_obj_is_kind_of(filename_location, rb_cString)) {
    fprintf(stdout, "opening %s. (flag=%d)\n", StringValuePtr(filename_location), dtype);
    rb_str_modify(filename_location);
    filename=StringValuePtr(filename_location);
    ptr->image = tsk_img_open_sing(filename, (TSK_IMG_TYPE_ENUM)type_flag_num, 0); // 0=default sector size
    if (ptr->image == NULL) rb_warn("unable to open image %s.\n", StringValuePtr(filename_location));

  }
  else if (rb_obj_is_kind_of(filename_location, rb_cArray)) {
    long i;
    typedef TSK_TCHAR * split_list;
    split_list images[255]; // to do: make array length reflect list's length

    for (i=0; i < RARRAY_LEN(filename_location); i++) {
      VALUE rstring = rb_ary_entry(filename_location, i);
      images[i] = StringValuePtr(rstring);
    }
    int count = (int)RARRAY_LEN(filename_location);

    ptr->image = tsk_img_open(count, (const TSK_TCHAR **)images, (TSK_IMG_TYPE_ENUM)type_flag_num, 0); // 0=default sector size
    VALUE arr_to_s = rb_funcall(filename_location, rb_intern("to_s"), 0, NULL);
    if (ptr->image == NULL) rb_warn("unable to open images %s.\n", StringValuePtr(arr_to_s));

  }
  else {
    rb_raise(rb_eArgError, "Arg1 should be String or Array of strings.");
  }

  if (ptr->image == NULL) {
    rb_funcall(self, rb_intern("taint"), 0, NULL);

    return Qnil;
    
  } else {
    TSK_IMG_INFO *image = ptr->image;

    img_size = LONG2NUM(image->size);
    img_sector_size = INT2NUM((int)image->sector_size);
    TSK_IMG_TYPE_ENUM typenum = image->itype;
    description = image_type_to_desc(self, INT2NUM(typenum));
    name = image_type_to_name(self, INT2NUM(typenum));

    rb_iv_set(self, "@size", img_size);
    rb_iv_set(self, "@sector_size", img_sector_size);
    rb_iv_set(self, "@type", INT2NUM((int)typenum));
    rb_iv_set(self, "@description", description);
    rb_iv_set(self, "@name", name);
    
    return self;
  }
}
Пример #27
0
VALUE CRbWin32API::call(int argc, VALUE * argv, VALUE obj)
{
	struct 
	{
		u32 params[16];
	} param;

	VALUE obj_proc		= rb_iv_get(obj, "__proc__");
	VALUE obj_import	= rb_iv_get(obj, "__import__");
	VALUE obj_export	= rb_iv_get(obj, "__export__");
	FARPROC ApiFunction	= (FARPROC)rb_num2ulong(obj_proc);

	VALUE args;

	int items	= rb_scan_args(argc, argv, "0*", &args);
	int nimport	= RARRAY_LEN(obj_import);

	if (items != nimport)
		rb_raise(rb_eSinError, "wrong number of parameters: expected %d, got %d", nimport, items);

	for (int i = 0; i < nimport; ++i) 
	{
		u32 lParam = 0;
		switch (FIX2INT(rb_ary_entry(obj_import, i))) 
		{
			VALUE str;
		case _T_NUMBER:
		case _T_INTEGER:
		default:
			lParam = rb_num2ulong(rb_ary_entry(args, i));
			break;
		case _T_POINTER:
			str = rb_ary_entry(args, i);
			if (NIL_P(str)) 
			{
				lParam = 0;
			} 
			else if (FIXNUM_P(str))
			{
				lParam = rb_num2ulong(str);
			} 
			else 
			{
				rb_string_value(&str);
				rb_str_modify(str);
				lParam = (u32)rb_string_value_ptr(&str);
			}
			break;
		}
		param.params[i] = lParam;
	}

	u32 retval;

	__try
	{
		__asm
		{
			mov			ebx, esp
			sub			esp, 40h
			mov			ecx, 10h
			lea			esi, [param]
			mov			edi, esp
			rep movs	dword ptr es:[edi], dword ptr [esi] 
			call        dword ptr [ApiFunction] 
			mov         esp, ebx
			mov         dword ptr [retval], eax 
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		rb_raise(rb_eSinError, "Api Crashed...");
	}

	switch (FIX2INT(obj_export)) 
	{
	case _T_NUMBER:
	case _T_INTEGER:
		return rb_int2inum(retval);
	case _T_POINTER:
		return (retval ? rb_str_new2((char *)retval) : Qnil);
	case _T_VOID:
	default:
		return INT2FIX(0);
	}
}
Пример #28
0
VALUE
rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_name, VALUE result)
{
    size_t size = 0, wpath_len = 0, wdir_len = 0, whome_len = 0;
    size_t buffer_len = 0;
    char *fullpath = NULL;
    wchar_t *wfullpath = NULL, *wpath = NULL, *wpath_pos = NULL;
    wchar_t *wdir = NULL, *wdir_pos = NULL;
    wchar_t *whome = NULL, *buffer = NULL, *buffer_pos = NULL;
    UINT path_cp, cp;
    VALUE path = fname, dir = dname;
    wchar_t wfullpath_buffer[PATH_BUFFER_SIZE];
    wchar_t path_drive = L'\0', dir_drive = L'\0';
    int ignore_dir = 0;
    rb_encoding *path_encoding;
    int tainted = 0;

    /* tainted if path is tainted */
    tainted = OBJ_TAINTED(path);

    /* get path encoding */
    if (NIL_P(dir)) {
	path_encoding = rb_enc_get(path);
    }
    else {
	path_encoding = rb_enc_check(path, dir);
    }

    cp = path_cp = code_page(path_encoding);

    /* workaround invalid codepage */
    if (path_cp == INVALID_CODE_PAGE) {
	cp = CP_UTF8;
	if (!NIL_P(path)) {
	    path = fix_string_encoding(path, path_encoding);
	}
    }

    /* convert char * to wchar_t */
    convert_mb_to_wchar(path, &wpath, &wpath_pos, &wpath_len, cp);

    /* determine if we need the user's home directory */
    /* expand '~' only if NOT rb_file_absolute_path() where `abs_mode` is 1 */
    if (abs_mode == 0 && wpath_len > 0 && wpath_pos[0] == L'~' &&
	(wpath_len == 1 || IS_DIR_SEPARATOR_P(wpath_pos[1]))) {
	/* tainted if expanding '~' */
	tainted = 1;

	whome = home_dir();
	if (whome == NULL) {
	    xfree(wpath);
	    rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'");
	}
	whome_len = wcslen(whome);

	if (PathIsRelativeW(whome) && !(whome_len >= 2 && IS_DIR_UNC_P(whome))) {
	    xfree(wpath);
	    rb_raise(rb_eArgError, "non-absolute home");
	}

	/* use filesystem encoding if expanding home dir */
	path_encoding = rb_filesystem_encoding();
	cp = path_cp = system_code_page();

	/* ignores dir since we are expading home */
	ignore_dir = 1;

	/* exclude ~ from the result */
	wpath_pos++;
	wpath_len--;

	/* exclude separator if present */
	if (wpath_len && IS_DIR_SEPARATOR_P(wpath_pos[0])) {
	    wpath_pos++;
	    wpath_len--;
	}
    }
    else if (wpath_len >= 2 && wpath_pos[1] == L':') {
	if (wpath_len >= 3 && IS_DIR_SEPARATOR_P(wpath_pos[2])) {
	    /* ignore dir since path contains a drive letter and a root slash */
	    ignore_dir = 1;
	}
	else {
	    /* determine if we ignore dir or not later */
	    path_drive = wpath_pos[0];
	}
    }
    else if (abs_mode == 0 && wpath_len >= 2 && wpath_pos[0] == L'~') {
	result = get_user_from_path(&wpath_pos, 1, cp, path_cp, path_encoding);

	if (wpath)
	    xfree(wpath);

	rb_raise(rb_eArgError, "can't find user %s", StringValuePtr(result));
    }

    /* convert dir */
    if (!ignore_dir && !NIL_P(dir)) {
	/* fix string encoding */
	if (path_cp == INVALID_CODE_PAGE) {
	    dir = fix_string_encoding(dir, path_encoding);
	}

	/* convert char * to wchar_t */
	convert_mb_to_wchar(dir, &wdir, &wdir_pos, &wdir_len, cp);

	if (abs_mode == 0 && wdir_len > 0 && wdir_pos[0] == L'~' &&
	    (wdir_len == 1 || IS_DIR_SEPARATOR_P(wdir_pos[1]))) {
	    /* tainted if expanding '~' */
	    tainted = 1;

	    whome = home_dir();
	    if (whome == NULL) {
		xfree(wpath);
		xfree(wdir);
		rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'");
	    }
	    whome_len = wcslen(whome);

	    if (PathIsRelativeW(whome) && !(whome_len >= 2 && IS_DIR_UNC_P(whome))) {
		xfree(wpath);
		xfree(wdir);
		rb_raise(rb_eArgError, "non-absolute home");
	    }

	    /* exclude ~ from the result */
	    wdir_pos++;
	    wdir_len--;

	    /* exclude separator if present */
	    if (wdir_len && IS_DIR_SEPARATOR_P(wdir_pos[0])) {
		wdir_pos++;
		wdir_len--;
	    }
	}
	else if (wdir_len >= 2 && wdir[1] == L':') {
	    dir_drive = wdir[0];
	    if (wpath_len && IS_DIR_SEPARATOR_P(wpath_pos[0])) {
		wdir_len = 2;
	    }
	}
	else if (wdir_len >= 2 && IS_DIR_UNC_P(wdir)) {
	    /* UNC path */
	    if (wpath_len && IS_DIR_SEPARATOR_P(wpath_pos[0])) {
		/* cut the UNC path tail to '//host/share' */
		size_t separators = 0;
		size_t pos = 2;
		while (pos < wdir_len && separators < 2) {
		    if (IS_DIR_SEPARATOR_P(wdir[pos])) {
			separators++;
		    }
		    pos++;
		}
		if (separators == 2)
		    wdir_len = pos - 1;
	    }
	}
	else if (abs_mode == 0 && wdir_len >= 2 && wdir_pos[0] == L'~') {
	    result = get_user_from_path(&wdir_pos, 1, cp, path_cp, path_encoding);
	    if (wpath)
		xfree(wpath);

	    if (wdir)
		xfree(wdir);

	    rb_raise(rb_eArgError, "can't find user %s", StringValuePtr(result));
	}
    }

    /* determine if we ignore dir or not */
    if (!ignore_dir && path_drive && dir_drive) {
	if (towupper(path_drive) == towupper(dir_drive)) {
	    /* exclude path drive letter to use dir */
	    wpath_pos += 2;
	    wpath_len -= 2;
	}
	else {
	    /* ignore dir since path drive is different from dir drive */
	    ignore_dir = 1;
	    wdir_len = 0;
	}
    }

    if (!ignore_dir && wpath_len >= 2 && IS_DIR_UNC_P(wpath)) {
	/* ignore dir since path has UNC root */
	ignore_dir = 1;
	wdir_len = 0;
    }
    else if (!ignore_dir && wpath_len >= 1 && IS_DIR_SEPARATOR_P(wpath[0]) &&
	     !dir_drive && !(wdir_len >= 2 && IS_DIR_UNC_P(wdir))) {
	/* ignore dir since path has root slash and dir doesn't have drive or UNC root */
	ignore_dir = 1;
	wdir_len = 0;
    }

    buffer_len = wpath_len + 1 + wdir_len + 1 + whome_len + 1;

    buffer = buffer_pos = (wchar_t *)xmalloc((buffer_len + 1) * sizeof(wchar_t));

    /* add home */
    if (whome_len) {
	wcsncpy(buffer_pos, whome, whome_len);
	buffer_pos += whome_len;
    }

    /* Add separator if required */
    if (whome_len && wcsrchr(L"\\/:", buffer_pos[-1]) == NULL) {
	buffer_pos[0] = L'\\';
	buffer_pos++;
    }

    if (wdir_len) {
	/* tainted if dir is used and dir is tainted */
	if (!tainted && OBJ_TAINTED(dir))
	    tainted = 1;

	wcsncpy(buffer_pos, wdir_pos, wdir_len);
	buffer_pos += wdir_len;
    }

    /* add separator if required */
    if (wdir_len && wcsrchr(L"\\/:", buffer_pos[-1]) == NULL) {
	buffer_pos[0] = L'\\';
	buffer_pos++;
    }

    /* now deal with path */
    if (wpath_len) {
	wcsncpy(buffer_pos, wpath_pos, wpath_len);
	buffer_pos += wpath_len;
    }

    /* GetFullPathNameW requires at least "." to determine current directory */
    if (wpath_len == 0) {
	buffer_pos[0] = L'.';
	buffer_pos++;
    }

    /* Ensure buffer is NULL terminated */
    buffer_pos[0] = L'\0';

    /* tainted if path is relative */
    if (!tainted && PathIsRelativeW(buffer) && !(buffer_len >= 2 && IS_DIR_UNC_P(buffer)))
	tainted = 1;

    /* FIXME: Make this more robust */
    /* Determine require buffer size */
    size = GetFullPathNameW(buffer, PATH_BUFFER_SIZE, wfullpath_buffer, NULL);
    if (size > PATH_BUFFER_SIZE) {
	/* allocate more memory than alloted originally by PATH_BUFFER_SIZE */
	wfullpath = (wchar_t *)xmalloc(size * sizeof(wchar_t));
	size = GetFullPathNameW(buffer, size, wfullpath, NULL);
    }
    else {
	wfullpath = wfullpath_buffer;
    }

    /* Remove any trailing slashes */
    if (IS_DIR_SEPARATOR_P(wfullpath[size - 1]) &&
	wfullpath[size - 2] != L':' &&
	!(size == 2 && IS_DIR_UNC_P(wfullpath))) {
	size -= 1;
	wfullpath[size] = L'\0';
    }

    /* Remove any trailing dot */
    if (wfullpath[size - 1] == L'.') {
	size -= 1;
	wfullpath[size] = L'\0';
    }

    /* removes trailing invalid ':$DATA' */
    size = remove_invalid_alternative_data(wfullpath, size);

    /* Replace the trailing path to long name */
    if (long_name)
	size = replace_to_long_name(&wfullpath, size, (wfullpath != wfullpath_buffer));

    /* sanitize backslashes with forwardslashes */
    replace_wchar(wfullpath, L'\\', L'/');

    /* convert to char * */
    size = WideCharToMultiByte(cp, 0, wfullpath, size, NULL, 0, NULL, NULL);
    if (size > (size_t)RSTRING_LEN(result)) {
	rb_str_modify(result);
	rb_str_resize(result, size);
    }

    WideCharToMultiByte(cp, 0, wfullpath, size, RSTRING_PTR(result), size, NULL, NULL);
    rb_str_set_len(result, size);

    /* convert to VALUE and set the path encoding */
    if (path_cp == INVALID_CODE_PAGE) {
	VALUE tmp;
	size_t len;

	rb_enc_associate(result, rb_utf8_encoding());
	ENC_CODERANGE_CLEAR(result);
	tmp = rb_str_encode(result, rb_enc_from_encoding(path_encoding), 0, Qnil);
	len = RSTRING_LEN(tmp);
	rb_str_modify(result);
	rb_str_resize(result, len);
	memcpy(RSTRING_PTR(result), RSTRING_PTR(tmp), len);
	rb_str_resize(tmp, 0);
    }
    rb_enc_associate(result, path_encoding);
    ENC_CODERANGE_CLEAR(result);

    /* makes the result object tainted if expanding tainted strings or returning modified path */
    if (tainted)
	OBJ_TAINT(result);

    /* TODO: better cleanup */
    if (buffer)
	xfree(buffer);

    if (wpath)
	xfree(wpath);

    if (wdir)
	xfree(wdir);

    if (whome)
	xfree(whome);

    if (wfullpath && wfullpath != wfullpath_buffer)
	xfree(wfullpath);

    if (fullpath)
	xfree(fullpath);

    return result;
}
Пример #29
0
/*
 * call-seq:
 *    Win32::API#call(arg1, arg2, ...)
 *
 * Calls the function pointer with the given arguments (if any). Note that,
 * while this method will catch some prototype mismatches (raising a TypeError
 * in the process), it is not fulproof.  It is ultimately your job to make
 * sure the arguments match the +prototype+ specified in the constructor.
 *
 * For convenience, nil is converted to NULL, true is converted to TRUE (1)
 * and false is converted to FALSE (0).
 */
static VALUE api_call(int argc, VALUE* argv, VALUE self){
   VALUE v_proto, v_args, v_arg, v_return;
   Win32API* ptr;
   unsigned long return_value;
   int i = 0;
   int len;

   struct{
      unsigned long params[20];
   } param;

   Data_Get_Struct(self, Win32API, ptr);

   rb_scan_args(argc, argv, "0*", &v_args);

   v_proto = rb_iv_get(self, "@prototype");

   // For void prototypes, allow either no args or an explicit nil
   if(RARRAY_LEN(v_proto) != RARRAY_LEN(v_args)){
      char* c = StringValuePtr(RARRAY_PTR(v_proto)[0]);
      if(!strcmp(c, "V")){
         rb_ary_push(v_args, Qnil);
      }
      else{
         rb_raise(rb_eArgError,
            "wrong number of parameters: expected %d, got %d",
            RARRAY_LEN(v_proto), RARRAY_LEN(v_args)
         );
      }
   }

   len = RARRAY_LEN(v_proto);

   for(i = 0; i < len; i++){
      v_arg = RARRAY_PTR(v_args)[i];

      // Convert nil to NULL.  Otherwise convert as appropriate.
      if(NIL_P(v_arg))
         param.params[i] = (unsigned long)NULL;
      else if(v_arg == Qtrue)
         param.params[i] = TRUE;
      else if(v_arg == Qfalse)
         param.params[i] = FALSE;
      else
         switch(ptr->prototype[i]){
            case _T_LONG:
               param.params[i] = NUM2ULONG(v_arg);
               break;
            case _T_INTEGER:
               param.params[i] = NUM2INT(v_arg);
               break;
            case _T_POINTER:
               if(FIXNUM_P(v_arg)){
                  param.params[i] = NUM2ULONG(v_arg);
               }
               else{
                  StringValue(v_arg);
                  rb_str_modify(v_arg);
                  param.params[i] = (unsigned long)StringValuePtr(v_arg);
               }
               break;
            case _T_CALLBACK:
               ActiveCallback = v_arg;
               v_proto = rb_iv_get(ActiveCallback, "@prototype");
               param.params[i] = (LPARAM)NUM2ULONG(rb_iv_get(ActiveCallback, "@address"));;
               break;
            case _T_STRING:
               param.params[i] = (unsigned long)RSTRING_PTR(v_arg);
               break;
            default:
               param.params[i] = NUM2ULONG(v_arg);
         }
   }

   /* Call the function, get the return value */
   return_value = ptr->function(param);


   /* Return the appropriate type based on the return type specified
    * in the constructor.
    */
   switch(ptr->return_type){
      case _T_INTEGER:
         v_return = INT2NUM(return_value);
         break;
      case _T_LONG:
         v_return = ULONG2NUM(return_value);
         break;
      case _T_VOID:
         v_return = Qnil;
         break;
      case _T_POINTER:
         if(!return_value){
            v_return = Qnil;
         }
         else{
            VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
            char* efunc = RSTRING_PTR(v_efunc);
            if(efunc[strlen(efunc)-1] == 'W'){
               v_return = rb_str_new(
                  (TCHAR*)return_value,
                  wcslen((wchar_t*)return_value)*2
               );
            }
            else{
               v_return = rb_str_new2((TCHAR*)return_value);
            }
         }
         break;
      case _T_STRING:
         {
            VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
            char* efunc = RSTRING_PTR(v_efunc);

            if(efunc[strlen(efunc)-1] == 'W'){
               v_return = rb_str_new(
                  (TCHAR*)return_value,
                  wcslen((wchar_t*)return_value)*2
               );
            }
            else{
               v_return = rb_str_new2((TCHAR*)return_value);
            }
         }
         break;
      default:
         v_return = INT2NUM(0);
   }

   return v_return;
}
Пример #30
0
DWORD CallbackFunction(CALLPARAM param, VALUE callback)
{
  VALUE v_proto, v_return, v_proc, v_retval;
  VALUE argv[20];
  int i, argc;
  char *a_proto;
  char *a_return;

  if(callback && !NIL_P(callback)){
    v_proto = rb_iv_get(callback, "@prototype");
    a_proto = RSTRING_PTR(v_proto);

    v_return = rb_iv_get(callback, "@return_type");
    a_return = RSTRING_PTR(v_return);

    v_proc = rb_iv_get(callback, "@function");
    argc = RSTRING_LEN(v_proto);

    for(i=0; i < RSTRING_LEN(v_proto); i++){
      argv[i] = Qnil;
      switch(a_proto[i]){
        case 'L':
          argv[i] = ULONG2NUM(param.params[i]);
          break;
        case 'P':
          if(param.params[i])
            argv[i] = rb_str_new2((char *)param.params[i]);
          break;
        case 'I':
          argv[i] = INT2NUM(param.params[i]);
          break;
        default:
          rb_raise(cAPIProtoError, "Illegal prototype '%s'", a_proto[i]);
      }
    }

    v_retval = rb_funcall2(v_proc, rb_intern("call"), argc, argv);

    /* Handle true and false explicitly, as some CALLBACK functions
     * require TRUE or FALSE to break out of loops, etc.
     */
    if(v_retval == Qtrue)
      return TRUE;
    else if(v_retval == Qfalse)
      return FALSE;

    switch (*a_return) {
      case 'I':
        return NUM2INT(v_retval);
        break;
      case 'L':
        return NUM2ULONG(v_retval);
        break;
      case 'S':
        return (unsigned long)RSTRING_PTR(v_retval);
        break;
      case 'P':
        if(NIL_P(v_retval)){
          return 0;
        }
        else if(FIXNUM_P(v_retval)){
          return NUM2ULONG(v_retval);
        }
        else{
          StringValue(v_retval);
          rb_str_modify(v_retval);
          return (unsigned long)StringValuePtr(v_retval);
        }
        break;
    }
  }

  return 0;
}