Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
--sort=no
--fields=+ilaKSe{extras}
--extras=-p

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
TestCase1 input.r /^TestCase1 <- R6::SomethingElse("TestCase1")$/;" globalVar language:R end:6
TestCase2 input.r /^TestCase2 <- R6::$/;" globalVar language:R end:10
TestCase3 input.r /^TestCase3 <- R6::R6Clas("TestCase3")$/;" globalVar language:R end:12
13 changes: 13 additions & 0 deletions Units/parser-r6class.r/r6-null-pointer-regression.d/input.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Test case for R6 parser null pointer regression
# This triggers the error path in r6ReadRightSideSymbol that was causing
# tokenDelete to be called with NULL pointers

# Case 1: R6:: followed by something other than R6Class
TestCase1 <- R6::SomethingElse("TestCase1")

# Case 2: Incomplete R6 namespace reference
TestCase2 <- R6::

# Case 3: R6 followed by :: but with syntax error
TestCase3 <- R6::R6Clas("TestCase3")

3 changes: 2 additions & 1 deletion main/tokeninfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ void flashTokenBacklog (struct tokenInfoClass *klass)

void tokenDelete (tokenInfo *token)
{
objPoolPut (token->klass->pool, token);
if (token != NULL)
objPoolPut (token->klass->pool, token);
}


Expand Down
13 changes: 7 additions & 6 deletions parsers/r-r6class.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,14 @@ static int r6ReadRightSideSymbol (rSubparser *s,
tokenInfo * token1 = NULL;
if (strcmp (tokenString (token), "R6") == 0)
{
tokenInfo * token0 = rNewToken ();
token0 = rNewToken ();
tokenRead (token0);
if (!tokenIsType (token0, R_SCOPE))
goto reject;
if (strcmp (tokenString (token0), "::"))
goto reject;

tokenInfo * token1 = rNewToken ();
token1 = rNewToken ();
tokenRead (token1);
if (!tokenIsType (token1, R_SYMBOL))
goto reject;
Expand All @@ -252,11 +252,12 @@ static int r6ReadRightSideSymbol (rSubparser *s,
}
return CORK_NIL;
reject:
if (token1)
/* For incomplete "R6::" cases, we don't want to unread the "::" token
as the main R parser may not handle it well. */
if (token1 && tokenIsType(token1, R_SYMBOL)) {
tokenUnread (token1);
if (token0)
tokenUnread (token0);
/* tokenDelete accepts NULL. */
}
/* Don't unread token0 (::) to prevent main parser confusion */
tokenDelete (token1);
tokenDelete (token0);

Expand Down
Loading