Repository: jerryscript-project/jerryscript
File: jerry-core/ecma/operations/ecma-objects.c (C)

Code before:
  ecma_value_t *names_buffer_p = prop_names_p->buffer_p;
  /* 3. */
  ecma_collection_t *properties_p = ecma_new_collection ();

  /* 4. */
  for (uint32_t i = 0; i < prop_names_p->item_count; i++)
  {
    /* 4.a */
    if (ecma_is_value_string (names_buffer_p[i]))
    {
      ecma_string_t *key_p = ecma_get_string_from_value (names_buffer_p[i]);

      /* 4.a.i */
      ecma_property_descriptor_t prop_desc;
      ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, key_p, &prop_desc);

      if (ECMA_IS_VALUE_ERROR (status))
      {
        ecma_collection_free (prop_names_p);
        ecma_collection_free (properties_p);

        return NULL;
      }

      /* 4.a.ii */
      if ((prop_desc.flags & ECMA_PROP_IS_ENUMERABLE) != 0)
      {
        /* 4.a.ii.1 */
        if (option == ECMA_ENUMERABLE_PROPERTY_KEYS)
        {
          ecma_collection_push_back (properties_p, ecma_copy_value (names_buffer_p[i]));
        }
        else
        {
          /* 4.a.ii.2.a */
          ecma_value_t value = ecma_op_object_get (obj_p, key_p);

          if (ECMA_IS_VALUE_ERROR (value))
          {
            ecma_collection_free (prop_names_p);
            ecma_collection_free (properties_p);

            return NULL;
          }

          /* 4.a.ii.2.b */
          if (option == ECMA_ENUMERABLE_PROPERTY_VALUES)
          {
            ecma_collection_push_back (properties_p, value);
          }
          else

Review comment (suggestion):
At this point `status` can be false which means that the requested property does not exist. In this case the property descriptor is uninitialized, therefore must not be freed.

Code after:
  ecma_value_t *names_buffer_p = prop_names_p->buffer_p;
  /* 3. */
  ecma_collection_t *properties_p = ecma_new_collection ();

  /* 4. */
  for (uint32_t i = 0; i < prop_names_p->item_count; i++)
  {
    /* 4.a */
    if (ecma_is_value_string (names_buffer_p[i]))
    {
      ecma_string_t *key_p = ecma_get_string_from_value (names_buffer_p[i]);

      /* 4.a.i */
      ecma_property_descriptor_t prop_desc;
      ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, key_p, &prop_desc);

      if (ECMA_IS_VALUE_ERROR (status))
      {
        ecma_collection_free (prop_names_p);
        ecma_collection_free (properties_p);

        return NULL;
      }

      const bool is_enumerable = (prop_desc.flags & ECMA_PROP_IS_ENUMERABLE) != 0;
      ecma_free_property_descriptor (&prop_desc);
      /* 4.a.ii */
      if (is_enumerable)
      {
        /* 4.a.ii.1 */
        if (option == ECMA_ENUMERABLE_PROPERTY_KEYS)
        {
          ecma_collection_push_back (properties_p, ecma_copy_value (names_buffer_p[i]));
        }
        else
        {
          /* 4.a.ii.2.a */
          ecma_value_t value = ecma_op_object_get (obj_p, key_p);

          if (ECMA_IS_VALUE_ERROR (value))
          {
            ecma_collection_free (prop_names_p);
            ecma_collection_free (properties_p);

            return NULL;
          }

          /* 4.a.ii.2.b */
          if (option == ECMA_ENUMERABLE_PROPERTY_VALUES)
          {
            ecma_collection_push_back (properties_p, value);