Repository: jerryscript-project/jerryscript
File: jerry-core/parser/js/js-parser-expr.c (C)

Code before:
  bool nullish_found = false;

  while (true)
  {
    uint8_t token = parser_stack_iterator_read_uint8 (&iterator);

    if (token == LEXER_EXPRESSION_START
        || token == LEXER_LEFT_PAREN
        || !LEXER_IS_BINARY_OP_TOKEN (token))
    {
      return;
    }

    parser_stack_iterator_skip (&iterator, sizeof (uint8_t));

    if (token == LEXER_ASSIGN)
    {
      cbc_opcode_t opcode = (cbc_opcode_t) parser_stack_iterator_read_uint8 (&iterator);

      if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG)
      {
        parser_stack_iterator_skip (&iterator, sizeof (uint16_t));
      }

      if (JERRY_UNLIKELY (context_p->stack_top_uint8 == LEXER_ASSIGN_GROUP_EXPR
                          || context_p->stack_top_uint8 == LEXER_ASSIGN_CONST))
      {
        parser_stack_iterator_skip (&iterator, sizeof (uint8_t));
      }
    }
    else if (token == LEXER_LOGICAL_OR || token == LEXER_LOGICAL_AND)
    {
      if (nullish_found)
      {
        parser_raise_error (context_p, PARSER_ERR_INVALID_NULLISH_COALESCING);
      }

      parser_stack_iterator_skip (&iterator, sizeof (parser_branch_t));
      logical_found = true;
    }
    else if (token == LEXER_NULLISH_COALESCING)
    {
      if (logical_found)
      {
        parser_raise_error (context_p, PARSER_ERR_INVALID_NULLISH_COALESCING);
      }

      parser_stack_iterator_skip (&iterator, sizeof (parser_branch_t));
      nullish_found = true;
    }
  }

Review comment (bug):
Both can happen at the same time, also accessing the `stack_top_uint8` is incorrect.

```c
token = parser_stack_iterator_read_uint8 (&iterator);

if (token == LEXER_ASSIGN_GROUP_EXPR) { parser_stack_iterator_skip (&iterator, sizeof (uint8_t));}
if (token == LEXER_ASSIGN_CONST) { parser_stack_iterator_skip (&iterator, sizeof (uint8_t));}
```


Code after:
  bool nullish_found = false;

  while (true)
  {
    uint8_t token = parser_stack_iterator_read_uint8 (&iterator);

    if (token == LEXER_EXPRESSION_START
        || token == LEXER_LEFT_PAREN
        || !LEXER_IS_BINARY_OP_TOKEN (token))
    {
      return;
    }

    parser_stack_iterator_skip (&iterator, sizeof (uint8_t));

    if (token == LEXER_ASSIGN)
    {
      cbc_opcode_t opcode = (cbc_opcode_t) parser_stack_iterator_read_uint8 (&iterator);

      if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG)
      {
        parser_stack_iterator_skip (&iterator, sizeof (uint16_t));
      }
      token = parser_stack_iterator_read_uint8 (&iterator);

      if (token == LEXER_ASSIGN_GROUP_EXPR)
      {
        parser_stack_iterator_skip (&iterator, sizeof (uint8_t));
      }
      if (token == LEXER_ASSIGN_CONST)
      {
        parser_stack_iterator_skip (&iterator, sizeof (uint8_t));
      }
    }
    else if (token == LEXER_LOGICAL_OR || token == LEXER_LOGICAL_AND)
    {
      if (nullish_found)
      {
        parser_raise_error (context_p, PARSER_ERR_INVALID_NULLISH_COALESCING);
      }

      parser_stack_iterator_skip (&iterator, sizeof (parser_branch_t));
      logical_found = true;
    }
    else if (token == LEXER_NULLISH_COALESCING)
    {
      if (logical_found)
      {
        parser_raise_error (context_p, PARSER_ERR_INVALID_NULLISH_COALESCING);
      }