예제 #1
0
int encode_field_array(lua_sandbox* lsb, output_data* d, int t,
                       const char* representation)
{
    int result = 0, first = 1;
    lua_checkstack(lsb->m_lua, 2);
    lua_pushnil(lsb->m_lua);
    while (result == 0 && lua_next(lsb->m_lua, -2) != 0) {
        // numerics are not packed, the space savings aren't worth the extra
        // buffer manipulation
        if (lua_type(lsb->m_lua, -1) != t) {
            snprintf(lsb->m_error_message, ERROR_SIZE, "array has mixed types");
            return 1;
        }
        result = encode_field_value(lsb, d, first, representation);
        first = 0;
        lua_pop(lsb->m_lua, 1); // Remove the value leaving the key on top for
                                // the next interation.
    }
    return result;
}
예제 #2
0
/**
 * Encodes a field that contains metadata in addition to its value.
 *
 * @param lsb  Pointer to the sandbox.
 * @param ob  Pointer to the output data buffer.
 *
 * @return lsb_err_value NULL on success error message on failure
 */
static lsb_err_value
encode_field_object(lsb_lua_sandbox *lsb, lsb_output_buffer *ob)
{
  const char *representation = NULL;
  lua_getfield(lsb->lua, -1, "representation");
  if (lua_isstring(lsb->lua, -1)) {
    representation = lua_tostring(lsb->lua, -1);
  }

  int value_type = -1;
  lua_getfield(lsb->lua, -2, "value_type");
  if (lua_isnumber(lsb->lua, -1)) {
    value_type = (int)lua_tointeger(lsb->lua, -1);
  }

  lua_getfield(lsb->lua, -3, "value");
  lsb_err_value ret = encode_field_value(lsb, ob, 1, representation, value_type);
  lua_pop(lsb->lua, 3); // remove representation, value_type and  value
  return ret;
}
예제 #3
0
/**
 * Encodes a field that has an array of values.
 *
 * @param lsb  Pointer to the sandbox.
 * @param ob  Pointer to the output data buffer.
 * @param t Lua type of the array values.
 * @param representation String representation of the field i.e., "ms"
 *
 * @return lsb_err_value NULL on success error message on failure
 */
static lsb_err_value
encode_field_array(lsb_lua_sandbox *lsb, lsb_output_buffer *ob, int t,
                   const char *representation, int value_type)
{
  lsb_err_value ret = NULL;
  int first = (int)lua_objlen(lsb->lua, -1);
  int multiple = first > 1 ? first : 0;
  size_t len_pos = 0;
  lua_checkstack(lsb->lua, 2);
  lua_pushnil(lsb->lua);
  while (!ret && lua_next(lsb->lua, -2) != 0) {
    if (lua_type(lsb->lua, -1) != t) {
      snprintf(lsb->error_message, LSB_ERROR_SIZE, "array has mixed types");
      return LSB_ERR_HEKA_INPUT;
    }
    ret = encode_field_value(lsb, ob, first, representation, value_type);
    if (first) {
      len_pos = ob->pos;
      first = 0;
    }
    lua_pop(lsb->lua, 1); // Remove the value leaving the key on top for
                          // the next interation.
  }
  if (!ret && multiple && value_type == LSB_PB_INTEGER) {
    // fix up the varint packed length
    size_t i = len_pos - 2;
    int y = 0;
    // find the length byte
    while (ob->buf[i] != 0 && y < LSB_MAX_VARINT_BYTES) {
      --i;
      ++y;
    }
    if (y == LSB_MAX_VARINT_BYTES) {
      snprintf(lsb->error_message, LSB_ERROR_SIZE,
               "unable set the length of the packed integer array");
      return LSB_ERR_LUA;
    }
    ret = lsb_pb_update_field_length(ob, i);
  }
  return ret;
}
예제 #4
0
/**
 * Iterates over the specified Lua table encoding the contents as user defined
 * message fields.
 *
 * @param lsb  Pointer to the sandbox.
 * @param ob  Pointer to the output data buffer.
 * @param tag Field identifier.
 * @param name Key used for the Lua table entry lookup.
 * @param index Lua stack index of the table.
 *
 * @return lsb_err_value NULL on success error message on failure
 */
static lsb_err_value
encode_fields(lsb_lua_sandbox *lsb, lsb_output_buffer *ob, char tag,
              const char *name, int index)
{
  lsb_err_value ret = NULL;
  lua_getfield(lsb->lua, index, name);
  if (!lua_istable(lsb->lua, -1)) {
    return ret;
  }

  lua_rawgeti(lsb->lua, -1, 1); // test for the array notation
  size_t len_pos, len;
  if (lua_istable(lsb->lua, -1)) {
    int i = 1;
    do {
      ret = lsb_pb_write_key(ob, tag, LSB_PB_WT_LENGTH);
      if (ret) return ret;

      len_pos = ob->pos;
      ret = lsb_pb_write_varint(ob, 0);  // length tbd later
      if (ret) return ret;

      lua_getfield(lsb->lua, -1, "name");
      if (lua_isstring(lsb->lua, -1)) {
        const char *s = lua_tolstring(lsb->lua, -1, &len);
        ret = lsb_pb_write_string(ob, LSB_PB_NAME, s, len);
      } else {
        snprintf(lsb->error_message, LSB_ERROR_SIZE,
                 "field name must be a string");
        ret = LSB_ERR_HEKA_INPUT;
      }
      lua_pop(lsb->lua, 1); // remove the name
      if (ret) return ret;

      ret = encode_field_object(lsb, ob);
      if (!ret) ret = lsb_pb_update_field_length(ob, len_pos);
      if (ret) return ret;

      lua_pop(lsb->lua, 1); // remove the current field object
      lua_rawgeti(lsb->lua, -1, ++i); // grab the next field object
    } while (!ret && !lua_isnil(lsb->lua, -1));
  } else {
    lua_pop(lsb->lua, 1); // remove the array test value
    lua_checkstack(lsb->lua, 2);
    lua_pushnil(lsb->lua);
    while (lua_next(lsb->lua, -2) != 0) {
      ret = lsb_pb_write_key(ob, tag, LSB_PB_WT_LENGTH);
      if (ret) return ret;

      len_pos = ob->pos;
      ret = lsb_pb_write_varint(ob, 0);  // length tbd later
      if (ret) return ret;

      if (lua_isstring(lsb->lua, -2)) {
        const char *s = lua_tolstring(lsb->lua, -2, &len);
        ret = lsb_pb_write_string(ob, LSB_PB_NAME, s, len);
      } else {
        snprintf(lsb->error_message, LSB_ERROR_SIZE,
                 "field name must be a string");
        ret = LSB_ERR_HEKA_INPUT;
      }
      if (ret) return ret;

      ret = encode_field_value(lsb, ob, 1, NULL, -1);
      if (!ret) ret = lsb_pb_update_field_length(ob, len_pos);
      if (ret) return ret;

      lua_pop(lsb->lua, 1); // Remove the value leaving the key on top for
                            // the next interation.
    }
  }
  lua_pop(lsb->lua, 1); // remove the fields table
  return ret;
}