int encode_fields(lua_sandbox* lsb, output_data* d, char id, const char* name,
                  int index)
{
  int result = 0;
  lua_getfield(lsb->lua, index, name);
  if (!lua_istable(lsb->lua, -1)) {
    return result;
  }

  size_t len_pos, len;
  lua_checkstack(lsb->lua, 2);
  lua_pushnil(lsb->lua);
  while (result == 0 && lua_next(lsb->lua, -2) != 0) {
    if (pb_write_tag(d, id, 2)) return 1;
    len_pos = d->pos;
    if (pb_write_varint(d, 0)) return 1;  // length tbd later
    if (lua_isstring(lsb->lua, -2)) {
      const char* s = lua_tolstring(lsb->lua, -2, &len);
      if (pb_write_string(d, 1, s, len)) return 1;
    } else {
      snprintf(lsb->error_message, LSB_ERROR_SIZE,
               "field name must be a string");
      return 1;
    }
    if (encode_field_value(lsb, d, 1, NULL)) return 1;
    if (update_field_length(d, len_pos)) return 1;
    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 result;
}
Example #2
0
int encode_string(lua_sandbox* lsb, output_data* d, char id, const char* name)
{
    int result = 0;
    lua_getfield(lsb->m_lua, 1, name);
    if (lua_isstring(lsb->m_lua, -1)) {
        size_t len;
        const char* s = lua_tolstring(lsb->m_lua, -1, &len);
        result = pb_write_string(d, id, s, len);
    }
    lua_pop(lsb->m_lua, 1);
    return result;
}
int encode_field_value(lua_sandbox* lsb, output_data* d, int first,
                       const char* representation)
{
  int result = 1;
  size_t len;
  const char* s;

  int t = lua_type(lsb->lua, -1);
  switch (t) {
  case LUA_TSTRING:
    if (first && representation) { // this uglyness keeps the protobuf
                                   // fields in order without additional
                                   // lookups
      if (pb_write_string(d, 3, representation, strlen(representation))) {
        return 1;
      }
    }
    s = lua_tolstring(lsb->lua, -1, &len);
    result = pb_write_string(d, 4, s, len);
    break;
  case LUA_TNUMBER:
    if (first) {
      if (pb_write_tag(d, 2, 0)) return 1;
      if (pb_write_varint(d, 3)) return 1;
      if (representation) {
        if (pb_write_string(d, 3, representation,
                            strlen(representation))) {
          return 1;
        }
      }
    }
    result = encode_double(lsb, d, 7);
    break;
  case LUA_TBOOLEAN:
    if (first) {
      if (pb_write_tag(d, 2, 0)) return 1;
      if (pb_write_varint(d, 4)) return 1;
      if (representation) {
        if (pb_write_string(d, 3, representation,
                            strlen(representation))) {
          return 1;
        }
      }
    }
    if (pb_write_tag(d, 8, 0)) return 1;
    result = pb_write_bool(d, lua_toboolean(lsb->lua, -1));
    break;
  case LUA_TTABLE:
    {
      lua_rawgeti(lsb->lua, -1, 1);
      int t = lua_type(lsb->lua, -1);
      lua_pop(lsb->lua, 1); // remove the array test value
      if (LUA_TNIL == t) {
        result = encode_field_object(lsb, d);
      } else {
        result = encode_field_array(lsb, d, t, representation);
      }
    }
    break;
  default:
    snprintf(lsb->error_message, LSB_ERROR_SIZE, "unsupported type %d", t);
    result = 1;
  }
  return result;
}