Beispiel #1
0
/**
 * Replace a 32 bit integer int the byte buffer.
 */
VALUE rb_bson_byte_buffer_replace_int32(VALUE self, VALUE index, VALUE i)
{
  byte_buffer_t *b;
  const int32_t position = NUM2LONG(index);
  const int32_t i32 = BSON_UINT32_TO_LE(NUM2LONG(i));

  TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);

  memcpy(READ_PTR(b) + position, &i32, 4);

  return self;
}
Beispiel #2
0
/**
 * Writes a 32 bit integer to the byte buffer.
 */
VALUE rb_bson_byte_buffer_put_int32(VALUE self, VALUE i)
{
  byte_buffer_t *b;
  const int32_t i32 = BSON_UINT32_TO_LE(NUM2INT(i));

  TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
  ENSURE_BSON_WRITE(b, 4);
  memcpy(WRITE_PTR(b), (char*)&i32, 4);
  b->write_position += 4;

  return self;
}
Beispiel #3
0
/**
 * Writes a string to the byte buffer.
 */
VALUE rb_bson_byte_buffer_put_string(VALUE self, VALUE string)
{
  byte_buffer_t *b;
  int32_t length_le;

  char *str = RSTRING_PTR(string);
  const int32_t length = RSTRING_LEN(string) + 1;
  length_le = BSON_UINT32_TO_LE(length);

  if (!rb_bson_utf8_validate(str, length - 1, true)) {
    rb_raise(rb_eArgError, "String %s is not valid UTF-8.", str);
  }

  TypedData_Get_Struct(self, byte_buffer_t, &rb_byte_buffer_data_type, b);
  ENSURE_BSON_WRITE(b, length + 4);
  memcpy(WRITE_PTR(b), (char*)&length_le, 4);
  b->write_position += 4;
  memcpy(WRITE_PTR(b), str, length);
  b->write_position += length;

  return self;
}
Beispiel #4
0
static void
test_bson_iter_fuzz (void)
{
   uint8_t *data;
   uint32_t len = 512;
   uint32_t len_le;
   uint32_t r;
   bson_iter_t iter;
   bson_t *b;
   uint32_t i;
   int pass;

   len_le = BSON_UINT32_TO_LE(len);

   for (pass = 0; pass < FUZZ_N_PASSES; pass++) {
      data = bson_malloc0(len);
      memcpy(data, &len_le, sizeof (len_le));

      for (i = 4; i < len; i += 4) {
         r = rand();
         memcpy(&data[i], &r, sizeof (r));
      }

      if (!(b = bson_new_from_data(data, len))) {
         /*
          * It could fail on buffer length or missing trailing null byte.
          */
         bson_free (data);
         continue;
      }

      BSON_ASSERT(b);

      /*
       * TODO: Most of the following ignores the key. That should be fixed
       *       but has it's own perils too.
       */

      assert(bson_iter_init(&iter, b));
      while (bson_iter_next(&iter)) {
         assert(iter.next_off < len);
         switch (bson_iter_type(&iter)) {
         case BSON_TYPE_ARRAY:
         case BSON_TYPE_DOCUMENT:
            {
               const uint8_t *child = NULL;
               uint32_t child_len = 0;

               bson_iter_document(&iter, &child_len, &child);
               if (child_len) {
                  assert(child);
                  assert(child_len >= 5);
                  assert((iter.off + child_len) < b->len);
                  assert(child_len < (uint32_t) -1);
                  memcpy(&child_len, child, sizeof (child_len));
                  child_len = BSON_UINT32_FROM_LE(child_len);
                  assert(child_len >= 5);
               }
            }
            break;
         case BSON_TYPE_DOUBLE:
         case BSON_TYPE_UTF8:
         case BSON_TYPE_BINARY:
         case BSON_TYPE_UNDEFINED:
            break;
         case BSON_TYPE_OID:
            assert(iter.off + 12 < iter.len);
            break;
         case BSON_TYPE_BOOL:
         case BSON_TYPE_DATE_TIME:
         case BSON_TYPE_NULL:
         case BSON_TYPE_REGEX:
            /* TODO: check for 2 valid cstring. */
         case BSON_TYPE_DBPOINTER:
         case BSON_TYPE_CODE:
         case BSON_TYPE_SYMBOL:
         case BSON_TYPE_CODEWSCOPE:
         case BSON_TYPE_INT32:
         case BSON_TYPE_TIMESTAMP:
         case BSON_TYPE_INT64:
         case BSON_TYPE_DECIMAL128:
         case BSON_TYPE_MAXKEY:
         case BSON_TYPE_MINKEY:
            break;
         case BSON_TYPE_EOD:
         default:
            /* Code should not be reached. */
            assert(false);
            break;
         }
      }

      bson_destroy(b);
      bson_free(data);
   }
}