Example #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;
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
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;
}