ronantakizawa/codereview-bench huggingface dataset:
Repository: jerryscript-project/jerryscript
File: jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c (C)

Code before:
  }

  ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index);
  ecma_value_t ret_value = ecma_builtin_helper_def_prop (obj_p, index_str_p, value, opts);
  ecma_deref_ecma_string (index_str_p);

  return ret_value;
} /* ecma_builtin_helper_def_prop_by_index */

/**
 * Helper function for at() functions.
 *
 * See also:
 *          ECMA-262 Stage 3 Draft Relative Indexing Method proposal 3. 4. 5. 6.
 *
 * Used by:
 *         - The Array.prototype.at routine.
 *         - The String.prototype.at routine.
 *         - The TypedArray.prototype.at routine.
 *
 * @return ECMA_VALUE_ERROR - on conversion error
 *         ECMA_VALUE_UNDEFINED - if the requested index is not exist
 *         ECMA_VALUE_EMPTY - otherwise
 */
ecma_value_t
ecma_builtin_helper_check_index (ecma_value_t index, /**< index argument */
                                 ecma_number_t *len) /**< [out] object's length */
{
  ecma_number_t relative_index;
  ecma_value_t conversion_result = ecma_op_to_integer (index, &relative_index);

   /* 4. */
  if (ECMA_IS_VALUE_ERROR (conversion_result))
  {
    return ECMA_VALUE_ERROR;
  }

  /* 5. 6. */
  ecma_number_t k;

  if (relative_index >= 0)
  {
    k = relative_index;
  }
  else
  {
    k = (*len + relative_index);
  }

  /* 7. */
  if (k < 0 || k >= (*len))

Review comment (suggestion):
For the "index argument" comment: I think we should highlight that the index is a *relative* index value. So the comment could be `relative index argument`.

Code after:
  }

  ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index);
  ecma_value_t ret_value = ecma_builtin_helper_def_prop (obj_p, index_str_p, value, opts);
  ecma_deref_ecma_string (index_str_p);

  return ret_value;
} /* ecma_builtin_helper_def_prop_by_index */

/**
 * Helper function for at() functions.
 *
 * See also:
 *          ECMA-262 Stage 3 Draft Relative Indexing Method proposal 3. 4. 5. 6.
 *
 * Used by:
 *         - The Array.prototype.at routine.
 *         - The String.prototype.at routine.
 *         - The TypedArray.prototype.at routine.
 *
 * @return ECMA_VALUE_ERROR - on conversion error
 *         ECMA_VALUE_UNDEFINED - if the requested index is not exist
 *         ECMA_VALUE_EMPTY - otherwise
 */
ecma_value_t
ecma_builtin_helper_calculate_index (ecma_value_t index, /**< relative index argument */
                                     ecma_length_t length, /**< object's length */
                                     ecma_length_t *out_index) /**< calculated index */
{
  JERRY_ASSERT (out_index != NULL);

  ecma_number_t relative_index;
  ecma_value_t conversion_result = ecma_op_to_integer (index, &relative_index);

   /* 4. */
  if (ECMA_IS_VALUE_ERROR (conversion_result))
  {
    return ECMA_VALUE_ERROR;
  }

  /* 5. 6. */
  ecma_number_t k;

  if (relative_index >= 0)
  {
    k = relative_index;
  }
  else
  {
    k = ((ecma_number_t) length + relative_index);
  }
Repository: jerryscript-project/jerryscript
File: jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c (C)

Code before:
  ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index);
  ecma_value_t ret_value = ecma_builtin_helper_def_prop (obj_p, index_str_p, value, opts);
  ecma_deref_ecma_string (index_str_p);

  return ret_value;
} /* ecma_builtin_helper_def_prop_by_index */

/**
 * Helper function for at() functions.
 *
 * See also:
 *          ECMA-262 Stage 3 Draft Relative Indexing Method proposal 3. 4. 5. 6.
 *
 * Used by:
 *         - The Array.prototype.at routine.
 *         - The String.prototype.at routine.
 *         - The TypedArray.prototype.at routine.
 *
 * @return ECMA_VALUE_ERROR - on conversion error
 *         ECMA_VALUE_UNDEFINED - if the requested index is not exist
 *         ECMA_VALUE_EMPTY - otherwise
 */
ecma_value_t
ecma_builtin_helper_calculate_index (ecma_value_t index, /**< relative index argument */
                                     ecma_length_t length, /**< object's length */
                                     ecma_length_t *out_index) /**< calculated index */
{
  ecma_number_t relative_index;
  ecma_value_t conversion_result = ecma_op_to_integer (index, &relative_index);

   /* 4. */
  if (ECMA_IS_VALUE_ERROR (conversion_result))
  {
    return ECMA_VALUE_ERROR;
  }

  /* 5. 6. */
  ecma_number_t k;

  if (relative_index >= 0)
  {
    k = relative_index;
  }
  else
  {
    k = ((ecma_number_t) length + relative_index);
  }

  /* 7. */
  if (k < 0 || k >= ((ecma_number_t) length))
  {

Review comment (suggestion):
We should add a an assert to make sure that the `out_index` is always a valid pointer (aka not null)

Code after:
  ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index);
  ecma_value_t ret_value = ecma_builtin_helper_def_prop (obj_p, index_str_p, value, opts);
  ecma_deref_ecma_string (index_str_p);

  return ret_value;
} /* ecma_builtin_helper_def_prop_by_index */

/**
 * Helper function for at() functions.
 *
 * See also:
 *          ECMA-262 Stage 3 Draft Relative Indexing Method proposal 3. 4. 5. 6.
 *
 * Used by:
 *         - The Array.prototype.at routine.
 *         - The String.prototype.at routine.
 *         - The TypedArray.prototype.at routine.
 *
 * @return ECMA_VALUE_ERROR - on conversion error
 *         ECMA_VALUE_UNDEFINED - if the requested index is not exist
 *         ECMA_VALUE_EMPTY - otherwise
 */
ecma_value_t
ecma_builtin_helper_calculate_index (ecma_value_t index, /**< relative index argument */
                                     ecma_length_t length, /**< object's length */
                                     ecma_length_t *out_index) /**< calculated index */
{
  JERRY_ASSERT (out_index != NULL);

  ecma_number_t relative_index;
  ecma_value_t conversion_result = ecma_op_to_integer (index, &relative_index);

   /* 4. */
  if (ECMA_IS_VALUE_ERROR (conversion_result))
  {
    return ECMA_VALUE_ERROR;
  }

  /* 5. 6. */
  ecma_number_t k;

  if (relative_index >= 0)
  {
    k = relative_index;
  }
  else
  {
    k = ((ecma_number_t) length + relative_index);
  }

  /* 7. */
Repository: jerryscript-project/jerryscript
File: jerry-core/parser/js/js-scanner-util.c (C)

Code before:
      {
        literal.char_p += data_p[2];
        next_data_p += 2 + 1;
      }
      else
      {
        memcpy (&literal.char_p, data_p + 2 + 1, sizeof (uintptr_t));
        next_data_p += 2 + 1 + sizeof (uintptr_t);
      }
    }
    else
    {
      int32_t diff = ((int32_t) data_p[2]) | ((int32_t) data_p[3]) << 8;

      if (diff <= (intptr_t) UINT8_MAX)
      {
        diff = -diff;
      }

      literal.char_p += diff;
      next_data_p += 2 + 2;
    }

    literal.length = data_p[1];
    literal.type = LEXER_IDENT_LITERAL;
    literal.status_flags = ((data_p[0] & SCANNER_STREAM_HAS_ESCAPE)
                             ? LEXER_LIT_LOCATION_HAS_ESCAPE
                             : LEXER_LIT_LOCATION_NO_OPTS);

    lexer_construct_literal_object (context_p, &literal, LEXER_NEW_IDENT_LITERAL);
    literal.char_p += data_p[1];

#if JERRY_MODULE_SYSTEM
    if (type == SCANNER_STREAM_TYPE_IMPORT)
    {
      continue;
    }
#endif /* JERRY_MODULE_SYSTEM */

    context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_USED;

    uint16_t opcode;
    if (type == SCANNER_STREAM_TYPE_VAR || type == SCANNER_STREAM_TYPE_FUNC)
    {
      opcode = CBC_CHECK_VAR;
    }
    else
    {
      opcode = CBC_CHECK_LET;
    }


Review comment (suggestion):
Move the `?` after this line
```
a = (condition ? a
               : b)
```

Code after:
        literal.char_p += data_p[2];
        next_data_p += 2 + 1;
      }
      else
      {
        memcpy (&literal.char_p, data_p + 2 + 1, sizeof (uintptr_t));
        next_data_p += 2 + 1 + sizeof (uintptr_t);
      }
    }
    else
    {
      int32_t diff = ((int32_t) data_p[2]) | ((int32_t) data_p[3]) << 8;

      if (diff <= (intptr_t) UINT8_MAX)
      {
        diff = -diff;
      }

      literal.char_p += diff;
      next_data_p += 2 + 2;
    }

    literal.length = data_p[1];
    literal.type = LEXER_IDENT_LITERAL;
    literal.status_flags = ((data_p[0] & SCANNER_STREAM_HAS_ESCAPE) ? LEXER_LIT_LOCATION_HAS_ESCAPE
                                                                    : LEXER_LIT_LOCATION_NO_OPTS);

    lexer_construct_literal_object (context_p, &literal, LEXER_NEW_IDENT_LITERAL);
    literal.char_p += data_p[1];

#if JERRY_MODULE_SYSTEM
    if (type == SCANNER_STREAM_TYPE_IMPORT)
    {
      continue;
    }
#endif /* JERRY_MODULE_SYSTEM */

    context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_USED;

    uint16_t opcode;
    if (type == SCANNER_STREAM_TYPE_VAR || type == SCANNER_STREAM_TYPE_FUNC)
    {
      opcode = CBC_CHECK_VAR;
    }
    else
    {
      opcode = CBC_CHECK_LET;
    }

    parser_emit_cbc_literal (context_p, opcode, context_p->lit_object.index);
  }
Repository: jerryscript-project/jerryscript
File: jerry-core/config.h (C/C++)

Code before:
#endif /* !defined (JERRY_BUILTIN_DATAVIEW) */

#ifndef JERRY_BUILTIN_GLOBAL_THIS
# define JERRY_BUILTIN_GLOBAL_THIS JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_GLOBAL_THIS) */

#ifndef JERRY_BUILTIN_PROMISE
# define JERRY_BUILTIN_PROMISE JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_PROMISE) */

#ifndef JERRY_BUILTIN_PROXY
# define JERRY_BUILTIN_PROXY JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_PROXY) */

#ifndef JERRY_BUILTIN_REALMS
# define JERRY_BUILTIN_REALMS JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_REALMS) */

#ifndef JERRY_BUILTIN_REFLECT
# define JERRY_BUILTIN_REFLECT JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_REFLECT) */

#ifndef JERRY_BUILTIN_TYPEDARRAY
# define JERRY_BUILTIN_TYPEDARRAY JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_TYPEDARRAY) */

#ifndef JERRY_BUILTIN_SHAREDARRAYBUFFER
# define JERRY_BUILTIN_SHAREDARRAYBUFFER JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_SHAREDARRAYBUFFER) */

#ifndef JERRY_BUILTIN_WEAKREF
# define JERRY_BUILTIN_WEAKREF JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_WEAKREF) */

#ifndef JERRY_MODULE_SYSTEM
# define JERRY_MODULE_SYSTEM JERRY_ESNEXT
#endif /* !defined (JERRY_MODULE_SYSTEM) */

/**
 * Engine internal and misc configurations.
 */

/**
 * Specifies the compressed pointer representation
 *
 * Allowed values:
 *  0: use 16 bit representation
 *  1: use 32 bit representation
 *
 * Default value: 0
 * For more details see: jmem/jmem.h

Review comment (suggestion):
JERRY_BUILTIN_SHAREDARRAYBUFFER should depend on JERRY_BUILTIN_TYPEDARRAY, it does not work otherwsie. We should have a check for this in this file.

Code after:
#endif /* !defined (JERRY_BUILTIN_DATAVIEW) */

#ifndef JERRY_BUILTIN_GLOBAL_THIS
# define JERRY_BUILTIN_GLOBAL_THIS JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_GLOBAL_THIS) */

#ifndef JERRY_BUILTIN_PROXY
# define JERRY_BUILTIN_PROXY JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_PROXY) */

#ifndef JERRY_BUILTIN_REALMS
# define JERRY_BUILTIN_REALMS JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_REALMS) */

#ifndef JERRY_BUILTIN_REFLECT
# define JERRY_BUILTIN_REFLECT JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_REFLECT) */

#ifndef JERRY_BUILTIN_TYPEDARRAY
# define JERRY_BUILTIN_TYPEDARRAY JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_TYPEDARRAY) */

#ifndef JERRY_BUILTIN_SHAREDARRAYBUFFER
# define JERRY_BUILTIN_SHAREDARRAYBUFFER JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_SHAREDARRAYBUFFER) */

#ifndef JERRY_BUILTIN_WEAKREF
# define JERRY_BUILTIN_WEAKREF JERRY_ESNEXT
#endif /* !defined (JERRY_BUILTIN_WEAKREF) */

#ifndef JERRY_MODULE_SYSTEM
# define JERRY_MODULE_SYSTEM JERRY_ESNEXT
#endif /* !defined (JERRY_MODULE_SYSTEM) */

/**
 * Engine internal and misc configurations.
 */

/**
 * Specifies the compressed pointer representation
 *
 * Allowed values:
 *  0: use 16 bit representation
 *  1: use 32 bit representation
 *
 * Default value: 0
 * For more details see: jmem/jmem.h
 */
#ifndef JERRY_CPOINTER_32_BIT
# define JERRY_CPOINTER_32_BIT 0
#endif /* !defined (JERRY_CPOINTER_32_BIT) */
Repository: jerryscript-project/jerryscript
File: jerry-core/ecma/operations/ecma-arraybuffer-object.c (C)

Code before:
#endif /* JERRY_BUILTIN_SHAREDARRAYBUFFER */

  if (ECMA_IS_VALUE_ERROR (ctor))
  {
    return ctor;
  }

  /* 12. */
  ecma_object_t *ctor_obj_p = ecma_get_object_from_value (ctor);
  ecma_value_t new_len_value = ecma_make_uint32_value (new_len);

  ecma_value_t new_arraybuffer = ecma_op_function_construct (ctor_obj_p, ctor_obj_p, &new_len_value, 1);

  ecma_deref_object (ctor_obj_p);
  ecma_free_value (new_len_value);

  if (ECMA_IS_VALUE_ERROR (new_arraybuffer))
  {
    return new_arraybuffer;
  }

  ecma_object_t *new_arraybuffer_p = ecma_get_object_from_value (new_arraybuffer);
  ecma_value_t ret_value = ECMA_VALUE_EMPTY;

  /* 13. */
  if (!(ecma_is_object_array_or_sharedarray_buffer (new_arraybuffer_p)))
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Return value is not an ArrayBuffer object"));
    goto free_new_arraybuffer;
  }

  /* 14-15. */
  if (ecma_arraybuffer_is_detached (new_arraybuffer_p))
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Returned ArrayBuffer has been detached"));
    goto free_new_arraybuffer;
  }

  /* 16. */
  if (new_arraybuffer == this_arg)
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer subclass returned this from species constructor"));
    goto free_new_arraybuffer;
  }

  /* 17. */
  if (ecma_arraybuffer_get_length (new_arraybuffer_p) < new_len)
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Derived ArrayBuffer constructor created a too small buffer"));
    goto free_new_arraybuffer;
  }

Review comment (suggestion):
No need for the parentheses after the `!`.: eg.:
```
if (!ecma_is_object_array_or_sharedarray_buffer (new_arraybuffer_p))
```

Code after:
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Returned ArrayBuffer has been detached"));
    goto free_new_arraybuffer;
  }

  /* 16. */
  if (new_arraybuffer == this_arg)
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer subclass returned this from species constructor"));
    goto free_new_arraybuffer;
  }

  /* 17. */
  if (ecma_arraybuffer_get_length (new_arraybuffer_p) < new_len)
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Derived ArrayBuffer constructor created a too small buffer"));
    goto free_new_arraybuffer;
  }

  /* 19. */
  if (ecma_arraybuffer_is_detached (object_p))
  {
    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Original ArrayBuffer has been detached"));
    goto free_new_arraybuffer;
  }

  /* 20. */
  lit_utf8_byte_t *old_buf = ecma_arraybuffer_get_buffer (object_p);

  /* 21. */
  lit_utf8_byte_t *new_buf = ecma_arraybuffer_get_buffer (new_arraybuffer_p);

  /* 22. */
  memcpy (new_buf, old_buf + start, new_len);

  free_new_arraybuffer:
  if (ret_value != ECMA_VALUE_EMPTY)
  {
    ecma_deref_object (new_arraybuffer_p);
  }
  else
  {
    /* 23. */
    ret_value = ecma_make_object_value (new_arraybuffer_p);
  }

  return ret_value;
} /* ecma_builtin_arraybuffer_slice */

/**
 * @}
 * @}
Repository: jerryscript-project/jerryscript
File: jerry-core/ecma/operations/ecma-shared-arraybuffer-object.c (C)

Code before:
 * Helper function: check if the target is SharedArrayBuffer
 *
 * See also: ES11 24.1.1.4
 *
 * @return true - if value is a SharedArrayBuffer object
 *         false - otherwise
 */
extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_is_shared_arraybuffer (ecma_value_t target) /**< the target value */
{
#if JERRY_BUILTIN_SHAREDARRAYBUFFER
  return (ecma_is_value_object (target)
          && ecma_object_class_is (ecma_get_object_from_value (target), ECMA_OBJECT_CLASS_SHARED_ARRAY_BUFFER));
#endif /* JERRY_BUILTIN_SHAREDARRAYBUFFER */
  JERRY_UNUSED (target);
  return false;
} /* ecma_is_shared_arraybuffer */

/**
 * Helper function: check if the target is SharedArrayBuffer Object
 *
 * @return true - if value is a SharedArrayBuffer object
 *         false - otherwise
 */
extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_is_shared_arraybuffer_object (ecma_object_t *object_p) /**< the target object */
{
#if JERRY_BUILTIN_SHAREDARRAYBUFFER
  return ecma_object_class_is (object_p, ECMA_OBJECT_CLASS_SHARED_ARRAY_BUFFER);
#endif /* JERRY_BUILTIN_SHAREDARRAYBUFFER */
  JERRY_UNUSED (object_p);
  return false;
} /* ecma_is_shared_arraybuffer_object */

/**
 * @}
 * @}
 */


Review comment (suggestion):
Was wondering what our naming scheme is. If I remember correctly if the argument is an object_t then `ecma_object` is the function prefix. So this method should be `ecma_object_is_shared_arraybuffer` (another example: `ecma_object_is_typedarray`)

Code after:
 * Helper function: check if the target is SharedArrayBuffer
 *
 * See also: ES11 24.1.1.4
 *
 * @return true - if value is a SharedArrayBuffer object
 *         false - otherwise
 */
extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_is_shared_arraybuffer (ecma_value_t target) /**< the target value */
{
#if JERRY_BUILTIN_SHAREDARRAYBUFFER
  return (ecma_is_value_object (target)
          && ecma_object_class_is (ecma_get_object_from_value (target), ECMA_OBJECT_CLASS_SHARED_ARRAY_BUFFER));
#else /* !JERRY_BUILTIN_SHAREDARRAYBUFFER */
  JERRY_UNUSED (target);
  return false;
#endif /* JERRY_BUILTIN_SHAREDARRAYBUFFER */
} /* ecma_is_shared_arraybuffer */

/**
 * Helper function: check if the target is SharedArrayBuffer Object
 *
 * @return true - if value is a SharedArrayBuffer object
 *         false - otherwise
 */
extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_object_is_shared_arraybuffer (ecma_object_t *object_p) /**< the target object */
{
#if JERRY_BUILTIN_SHAREDARRAYBUFFER
  return ecma_object_class_is (object_p, ECMA_OBJECT_CLASS_SHARED_ARRAY_BUFFER);
#else /* !JERRY_BUILTIN_SHAREDARRAYBUFFER */
  JERRY_UNUSED (object_p);
  return false;
#endif /* JERRY_BUILTIN_SHAREDARRAYBUFFER */
} /* ecma_object_is_shared_arraybuffer */

/**
 * @}
 * @}
 */
Repository: jerryscript-project/jerryscript
File: jerry-core/lit/lit-strings.c (C)

Code before:
 *   Isolated surrogates are allowed.
 *
 * @return true if utf-8 string is well-formed
 *         false otherwise
 */
bool
lit_is_valid_utf8_string (const lit_utf8_byte_t *utf8_buf_p, /**< utf-8 string */
                          lit_utf8_size_t buf_size, /**< string size */
                          bool is_strict) /**< true if surrogate pairs are not allowed */
{
  const unsigned char *end = buf_size + utf8_buf_p;

  const unsigned char *idx = (const unsigned char *) utf8_buf_p;

  while (idx < end)
  {
    const unsigned char c = *idx++;

    if (c <= 0x7f)
    {
      continue;
    }

    const unsigned char d = *idx++;

    if ((c & 0xe0) == 0xc0)
    {
      if ((d & 0xc0) != 0x80 || (c & 0xfe) == 0xc0)
      {
        return false;
      }
      continue;
    }

    const unsigned char e = *idx++;

    if ((c & 0xf0) == 0xe0)
    {
      if ((d & 0xc0) != 0x80 || (e & 0xc0) != 0x80 || (c == 0xe0 && (d & 0xe0) == 0x80)
           || (!is_strict && c != 0xed && (d & 0xe0) == 0xa0))
      {
        return false;
      }
      continue;
    }

    const unsigned char f = *idx++;

    if ((c & 0xf8) == 0xf0)
    {
      if ((d & 0xc0) != 0x80 || (e & 0xc0) != 0x80 || (f & 0xc0) != 0x80 || (c == 0xf0 && (d & 0xf0) == 0x80)

Review comment (bug):
`if (c <= 0xe1) return false` could simplify the check in line 51. Also `(d & 0xc0) != 0x80` check could be done here as well, since it is needed by all cases later. Furthermore a length check before `*idx++` is missing, which may lead to segfault.

Code after:
#define LIT_UTF8_LOW_SURROGATE_MAX 0xbf /**< utf8 low surrogate maximum */
#define LIT_UTF8_1_BYTE_MAX 0xf4 /**< utf8 one byte max */
#define LIT_UTF8_2_BYTE_MAX 0x8f /**< utf8 two byte max */
#define LIT_UTF8_VALID_TWO_BYTE_START 0xc2 /**< utf8 two byte start */

/**
 * Validate utf-8 string
 *
 * NOTE:
 *   Isolated surrogates are allowed.
 *
 * @return true if utf-8 string is well-formed
 *         false otherwise
 */
bool
lit_is_valid_utf8_string (const lit_utf8_byte_t *utf8_buf_p, /**< utf-8 string */
                          lit_utf8_size_t buf_size, /**< string size */
                          bool is_strict) /**< true if surrogate pairs are not allowed */
{
  const unsigned char *end = buf_size + utf8_buf_p;

  const unsigned char *idx = (const unsigned char *) utf8_buf_p;

  while (idx < end)
  {
    const uint8_t first_byte = *idx++;

    if (first_byte < LIT_UTF8_EXTRA_BYTE_MARKER)
    {
      continue;
    }

    if (first_byte < LIT_UTF8_VALID_TWO_BYTE_START || idx >= end)
    {
      return false;
    }

    const uint8_t second_byte = *idx++;

    if ((second_byte & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
    {
      return false;
    }

    if (first_byte < LIT_UTF8_3_BYTE_MARKER)
    {
      continue;
    }

    if (idx >= end || (*idx++ & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
    {
Repository: jerryscript-project/jerryscript
File: jerry-core/lit/lit-strings.c (C)

Code before:
      return false;
    }

    if (first_byte < LIT_UTF8_3_BYTE_MARKER)
    {
      continue;
    }

    if (idx >= end || ((*idx++ & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER))
    {
      return false;
    }

    if (first_byte < LIT_UTF8_4_BYTE_MARKER)
    {
      if ((first_byte == LIT_UTF8_3_BYTE_MARKER && (second_byte & LIT_UTF8_2_BYTE_MASK) == LIT_UTF8_EXTRA_BYTE_MARKER))
      {
        return false;
      }

      if (first_byte == LIT_UTF8_SURROGATE_MARKER
          && second_byte >= LIT_UTF8_HIGH_SURROGATE_MIN
          && second_byte <= LIT_UTF8_HIGH_SURROGATE_MAX
          && *idx++ == LIT_UTF8_SURROGATE_MARKER)
      {
        const uint8_t fifth_byte = *idx++;
        if (!is_strict && fifth_byte >= LIT_UTF8_LOW_SURROGATE_MIN && fifth_byte <= LIT_UTF8_LOW_SURROGATE_MAX)
        {
          idx++;
          continue;
        }
        else
        {
          return false;
        }
      }
      continue;
    }

    if (idx >= end
        || ((*idx++ & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
        || first_byte >= LIT_UTF8_4_BYTE_MASK
        || first_byte > LIT_UTF8_1_BYTE_MAX)
    {
      return false;
    }

    if ((first_byte == LIT_UTF8_4_BYTE_MARKER
        && (second_byte & LIT_UTF8_3_BYTE_MASK) == LIT_UTF8_EXTRA_BYTE_MARKER)
        || (first_byte == LIT_UTF8_1_BYTE_MAX
            && second_byte > LIT_UTF8_2_BYTE_MAX))

Review comment (suggestion):
fifth_byte? I am not sure everything is checked here.

This should looks like this:

First check the third byte, its value is irrelevant.

`if (is_strict && first_byte == surrogate_marker && second_byte in surrogate && idx + 3 <= end && check the other 3 bytes) -> return false;`

Code after:
      return false;
    }

    if (first_byte < LIT_UTF8_3_BYTE_MARKER)
    {
      continue;
    }

    if (idx >= end || (*idx++ & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
    {
      return false;
    }

    if (first_byte < LIT_UTF8_4_BYTE_MARKER)
    {
      if (first_byte == LIT_UTF8_3_BYTE_MARKER && (second_byte & LIT_UTF8_2_BYTE_MASK) == LIT_UTF8_EXTRA_BYTE_MARKER)
      {
        return false;
      }

      if (is_strict
          && first_byte == LIT_UTF8_SURROGATE_MARKER
          && second_byte >= LIT_UTF8_HIGH_SURROGATE_MIN
          && second_byte <= LIT_UTF8_HIGH_SURROGATE_MAX
          && idx + 3 <= end
          && idx[0] == LIT_UTF8_SURROGATE_MARKER
          && idx[1] >= LIT_UTF8_LOW_SURROGATE_MIN
          && idx[1] <= LIT_UTF8_LOW_SURROGATE_MAX)
      {
        return false;
      }
      continue;
    }

    if (idx >= end
        || first_byte > LIT_UTF8_1_BYTE_MAX
        || (first_byte == LIT_UTF8_4_BYTE_MARKER && second_byte <= LIT_UTF8_EXTRA_BYTE_MARKER)
        || (first_byte == LIT_UTF8_1_BYTE_MAX && second_byte > LIT_UTF8_2_BYTE_MAX)
        || (*idx++ & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
    {
      return false;
    }
  }

  return true;
} /* lit_is_valid_utf8_string */

/**
 * Validate cesu-8 string
 *
 * @return true if cesu-8 string is well-formed