Exemple #1
0
static tr_variant*
get_node (tr_ptrArray * stack, tr_quark * key, tr_variant * top, int * err)
{
  tr_variant * node = NULL;

  if (tr_ptrArrayEmpty (stack))
    {
      node = top;
    }
  else
    {
      tr_variant * parent = tr_ptrArrayBack (stack);

      if (tr_variantIsList (parent))
        {
          node = tr_variantListAdd (parent);
        }
      else if (*key && tr_variantIsDict (parent))
        {
          node = tr_variantDictAdd (parent, *key);
          *key = 0;
        }
      else
        {
          *err = EILSEQ;
        }
    }

  return node;
}
Exemple #2
0
static tr_variant*
get_node (struct jsonsl_st * jsn)
{
  tr_variant * parent;
  tr_variant * node = NULL;
  struct json_wrapper_data * data = jsn->data;

  parent = tr_ptrArrayEmpty (&data->stack)
         ? NULL
         : tr_ptrArrayBack (&data->stack);

  if (!parent)
    {
      node = data->top;
    }
  else if (tr_variantIsList (parent))
    {
      node = tr_variantListAdd (parent);
    }
  else if (tr_variantIsDict (parent) && (data->key!=NULL))
    {
      node = tr_variantDictAdd (parent, tr_quark_new (data->key, data->keylen));

      data->key = NULL;
      data->keylen = 0;
    }

  return node;
}
Exemple #3
0
void
tr_cacheFree (tr_cache * cache)
{
  assert (tr_ptrArrayEmpty (&cache->blocks));
  tr_ptrArrayDestruct (&cache->blocks, NULL);
  tr_free (cache);
}
static tr_benc*
get_node (struct jsonsl_st * jsn)
{
  tr_benc * parent;
  tr_benc * node = NULL;
  struct json_wrapper_data * data = jsn->data;

  parent = tr_ptrArrayEmpty (&data->stack)
         ? NULL
         : tr_ptrArrayBack (&data->stack);

  if (!parent)
    {
      node = data->top;
    }
  else if (tr_bencIsList (parent))
    {
      node = tr_bencListAdd (parent);
    }
  else if (tr_bencIsDict (parent) && (data->key!=NULL))
    {
      node = tr_bencDictAdd (parent, data->key);
      tr_free (data->key);
      data->key = NULL;
    }

  return node;
}
Exemple #5
0
bool
tr_quark_lookup (const void * str, size_t len, tr_quark * setme)
{
  struct tr_key_struct tmp;
  struct tr_key_struct * match;
  static const size_t n_static = sizeof(my_static) / sizeof(struct tr_key_struct);
  bool success = false;

  assert (n_static == TR_N_KEYS);

  tmp.str = str;
  tmp.len = len;

  /* is it in our static array? */
  match = bsearch (&tmp, my_static, n_static, sizeof(struct tr_key_struct), compareKeys);
  if (match != NULL)
    {
      *setme = match - my_static;
      success = true;
    }

  /* was it added during runtime? */
  if (!success && !tr_ptrArrayEmpty(&my_runtime))
    {
      size_t i;
      struct tr_key_struct ** runtime = (struct tr_key_struct **) tr_ptrArrayBase (&my_runtime);
      const size_t n_runtime = tr_ptrArraySize (&my_runtime);
      for (i=0; i<n_runtime; ++i)
        {
          if (compareKeys (&tmp, runtime[i]) == 0)
            {
              *setme = TR_N_KEYS + i;
              success = true;
              break;
            }
        }
    }

  return success;
}
Exemple #6
0
static tr_benc*
getNode( struct json_benc_data * data )
{
    tr_benc * parent;
    tr_benc * node = NULL;

    if( tr_ptrArrayEmpty( data->stack ) )
        parent = NULL;
    else
        parent = tr_ptrArrayBack( data->stack );

    if( !parent )
        node = data->top;
    else if( tr_bencIsList( parent ) )
        node = tr_bencListAdd( parent );
    else if( tr_bencIsDict( parent ) && data->key )
    {
        node = tr_bencDictAdd( parent, data->key );
        tr_free( data->key );
        data->key = NULL;
    }

    return node;
}
Exemple #7
0
/**
 * This function's previous recursive implementation was
 * easier to read, but was vulnerable to a smash-stacking
 * attack via maliciously-crafted bencoded data. (#667)
 */
int
tr_variantParseBenc (const void    * buf_in,
                     const void    * bufend_in,
                     tr_variant    * top,
                     const char   ** setme_end)
{
  int err = 0;
  const uint8_t * buf = buf_in;
  const uint8_t * bufend = bufend_in;
  tr_ptrArray stack = TR_PTR_ARRAY_INIT;
  tr_quark key = 0;

  tr_variantInit (top, 0);

  while (buf != bufend)
    {
      if (buf > bufend) /* no more text to parse... */
        err = EILSEQ;

      if (err)
        break;

      if (*buf == 'i') /* int */
        {
          int64_t val;
          const uint8_t * end;
          tr_variant * v;

          if ((err = tr_bencParseInt (buf, bufend, &end, &val)))
            break;
          buf = end;

          if ((v = get_node (&stack, &key, top, &err)))
            tr_variantInitInt (v, val);
        }
      else if (*buf == 'l') /* list */
        {
          tr_variant * v;

          ++buf;

          if ((v = get_node (&stack, &key, top, &err)))
            {
              tr_variantInitList (v, 0);
              tr_ptrArrayAppend (&stack, v);
            }
        }
      else if (*buf == 'd') /* dict */
        {
          tr_variant * v;

          ++buf;

          if ((v = get_node (&stack, &key, top, &err)))
            {
              tr_variantInitDict (v, 0);
              tr_ptrArrayAppend (&stack, v);
            }
        }
      else if (*buf == 'e') /* end of list or dict */
        {
          ++buf;

          if (tr_ptrArrayEmpty (&stack) || (key != 0))
            {
              err = EILSEQ;
              break;
            }
          else
            {
              tr_ptrArrayPop (&stack);
              if (tr_ptrArrayEmpty (&stack))
                break;
            }
        }
      else if (isdigit (*buf)) /* string? */
        {
          tr_variant * v;
          const uint8_t * end;
          const uint8_t * str;
          size_t str_len;

          if ((err = tr_bencParseStr (buf, bufend, &end, &str, &str_len)))
            break;
          buf = end;

          if (!key && !tr_ptrArrayEmpty(&stack) && tr_variantIsDict(tr_ptrArrayBack(&stack)))
            key = tr_quark_new (str, str_len);
          else if ((v = get_node (&stack, &key, top, &err)))
            tr_variantInitStr (v, str, str_len);
        }
      else /* invalid bencoded text... march past it */
        {
          ++buf;
        }

      if (tr_ptrArrayEmpty (&stack))
        break;
    }

  if (!err && (!top->type || !tr_ptrArrayEmpty(&stack)))
    err = EILSEQ;

  if (!err && setme_end)
    *setme_end = (const char*) buf;

  tr_ptrArrayDestruct (&stack, NULL);
  return err;
}