Skip to content

Commit

Permalink
Fixes #4317. range endpoints with () will generate an NPE
Browse files Browse the repository at this point in the history
  • Loading branch information
enebo committed Nov 17, 2016
1 parent e01d2b5 commit ffc235a
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 45 deletions.
39 changes: 17 additions & 22 deletions core/src/main/java/org/jruby/parser/RubyParser.java
Expand Up @@ -84,7 +84,6 @@
import org.jruby.ast.NonLocalControlFlowNode;
import org.jruby.ast.NumericNode;
import org.jruby.ast.OpAsgnAndNode;
import org.jruby.ast.OpAsgnNode;
import org.jruby.ast.OpAsgnOrNode;
import org.jruby.ast.OptArgNode;
import org.jruby.ast.PostExeNode;
Expand Down Expand Up @@ -119,11 +118,9 @@
import org.jruby.lexer.LexerSource;
import org.jruby.lexer.yacc.RubyLexer;
import org.jruby.lexer.yacc.StrTerm;
import org.jruby.lexer.yacc.SyntaxException;
import org.jruby.lexer.yacc.SyntaxException.PID;
import org.jruby.util.ByteList;
import org.jruby.util.KeyValuePair;
import org.jruby.util.cli.Options;
import org.jruby.util.StringSupport;
import static org.jruby.lexer.LexingCommon.EXPR_BEG;
import static org.jruby.lexer.LexingCommon.EXPR_FITEM;
Expand Down Expand Up @@ -160,7 +157,7 @@ public void setWarnings(IRubyWarnings warnings) {
support.setWarnings(warnings);
lexer.setWarnings(warnings);
}
// line 164 "-"
// line 161 "-"
// %token constants
public static final int kCLASS = 257;
public static final int kMODULE = 258;
Expand Down Expand Up @@ -1561,7 +1558,7 @@ protected String[] yyExpecting (int state) {
/** the generated parser, with debugging messages.
Maintains a dynamic state and value stack.
@param yyLex scanner.
@param yydebug debug message writer implementing <tt>yyDebug</tt>, or <tt>null</tt>.
@param ayydebug debug message writer implementing <tt>yyDebug</tt>, or <tt>null</tt>.
@return result of the last reduction, if any.
*/
public Object yyparse (RubyLexer yyLex, Object ayydebug)
Expand Down Expand Up @@ -1787,8 +1784,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
node = support.appendToBlock(((Node)yyVals[-3+yyTop]), ((Node)yyVals[-1+yyTop]));
}
if (((Node)yyVals[0+yyTop]) != null) {
if (node == null) node = NilImplicitNode.NIL;
node = new EnsureNode(support.getPosition(((Node)yyVals[-3+yyTop])), node, ((Node)yyVals[0+yyTop]));
node = new EnsureNode(support.getPosition(((Node)yyVals[-3+yyTop])), support.makeNullNil(node), ((Node)yyVals[0+yyTop]));
}

support.fixpos(node, ((Node)yyVals[-3+yyTop]));
Expand Down Expand Up @@ -1837,7 +1833,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
};
states[19] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
yyVal = new BeginNode(((ISourcePosition)yyVals[-4+yyTop]), ((Node)yyVals[-3+yyTop]) == null ? NilImplicitNode.NIL : ((Node)yyVals[-3+yyTop]));
yyVal = new BeginNode(((ISourcePosition)yyVals[-4+yyTop]), support.makeNullNil(((Node)yyVals[-3+yyTop])));
return yyVal;
}
};
Expand Down Expand Up @@ -2959,7 +2955,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
support.checkExpression(((Node)yyVals[0+yyTop]));

boolean isLiteral = ((Node)yyVals[-2+yyTop]) instanceof FixnumNode && ((Node)yyVals[0+yyTop]) instanceof FixnumNode;
yyVal = new DotNode(support.getPosition(((Node)yyVals[-2+yyTop])), ((Node)yyVals[-2+yyTop]), ((Node)yyVals[0+yyTop]), false, isLiteral);
yyVal = new DotNode(support.getPosition(((Node)yyVals[-2+yyTop])), support.makeNullNil(((Node)yyVals[-2+yyTop])), support.makeNullNil(((Node)yyVals[0+yyTop])), false, isLiteral);
return yyVal;
}
};
Expand All @@ -2969,7 +2965,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
support.checkExpression(((Node)yyVals[0+yyTop]));

boolean isLiteral = ((Node)yyVals[-2+yyTop]) instanceof FixnumNode && ((Node)yyVals[0+yyTop]) instanceof FixnumNode;
yyVal = new DotNode(support.getPosition(((Node)yyVals[-2+yyTop])), ((Node)yyVals[-2+yyTop]), ((Node)yyVals[0+yyTop]), true, isLiteral);
yyVal = new DotNode(support.getPosition(((Node)yyVals[-2+yyTop])), support.makeNullNil(((Node)yyVals[-2+yyTop])), support.makeNullNil(((Node)yyVals[0+yyTop])), true, isLiteral);
return yyVal;
}
};
Expand Down Expand Up @@ -3168,7 +3164,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
states[262] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
support.checkExpression(((Node)yyVals[0+yyTop]));
yyVal = ((Node)yyVals[0+yyTop]) != null ? ((Node)yyVals[0+yyTop]) : NilImplicitNode.NIL;
yyVal = support.makeNullNil(((Node)yyVals[0+yyTop]));
return yyVal;
}
};
Expand Down Expand Up @@ -3382,7 +3378,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
states[306] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
lexer.getCmdArgumentState().reset(((Long)yyVals[-2+yyTop]).longValue());
yyVal = new BeginNode(((ISourcePosition)yyVals[-3+yyTop]), ((Node)yyVals[-1+yyTop]) == null ? NilImplicitNode.NIL : ((Node)yyVals[-1+yyTop]));
yyVal = new BeginNode(((ISourcePosition)yyVals[-3+yyTop]), support.makeNullNil(((Node)yyVals[-1+yyTop])));
return yyVal;
}
};
Expand Down Expand Up @@ -3551,7 +3547,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
};
states[332] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
Node body = ((Node)yyVals[-1+yyTop]) == null ? NilImplicitNode.NIL : ((Node)yyVals[-1+yyTop]);
Node body = support.makeNullNil(((Node)yyVals[-1+yyTop]));
yyVal = new WhileNode(((ISourcePosition)yyVals[-6+yyTop]), support.getConditionNode(((Node)yyVals[-4+yyTop])), body);
return yyVal;
}
Expand All @@ -3570,7 +3566,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
};
states[335] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
Node body = ((Node)yyVals[-1+yyTop]) == null ? NilImplicitNode.NIL : ((Node)yyVals[-1+yyTop]);
Node body = support.makeNullNil(((Node)yyVals[-1+yyTop]));
yyVal = new UntilNode(((ISourcePosition)yyVals[-6+yyTop]), support.getConditionNode(((Node)yyVals[-4+yyTop])), body);
return yyVal;
}
Expand Down Expand Up @@ -3617,7 +3613,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
};
states[342] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
Node body = ((Node)yyVals[-1+yyTop]) == null ? NilImplicitNode.NIL : ((Node)yyVals[-1+yyTop]);
Node body = support.makeNullNil(((Node)yyVals[-1+yyTop]));

yyVal = new ClassNode(((ISourcePosition)yyVals[-5+yyTop]), ((Colon3Node)yyVals[-4+yyTop]), support.getCurrentScope(), body, ((Node)yyVals[-3+yyTop]));
support.popCurrentScope();
Expand All @@ -3641,7 +3637,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
};
states[345] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
Node body = ((Node)yyVals[-1+yyTop]) == null ? NilImplicitNode.NIL : ((Node)yyVals[-1+yyTop]);
Node body = support.makeNullNil(((Node)yyVals[-1+yyTop]));

yyVal = new SClassNode(((ISourcePosition)yyVals[-7+yyTop]), ((Node)yyVals[-5+yyTop]), support.getCurrentScope(), body);
support.popCurrentScope();
Expand All @@ -3661,7 +3657,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
};
states[347] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
Node body = ((Node)yyVals[-1+yyTop]) == null ? NilImplicitNode.NIL : ((Node)yyVals[-1+yyTop]);
Node body = support.makeNullNil(((Node)yyVals[-1+yyTop]));

yyVal = new ModuleNode(((ISourcePosition)yyVals[-4+yyTop]), ((Colon3Node)yyVals[-3+yyTop]), support.getCurrentScope(), body);
support.popCurrentScope();
Expand All @@ -3679,8 +3675,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
};
states[349] = new ParserState() {
@Override public Object execute(ParserSupport support, RubyLexer lexer, Object yyVal, Object[] yyVals, int yyTop) {
Node body = ((Node)yyVals[-1+yyTop]);
if (body == null) body = NilImplicitNode.NIL;
Node body = support.makeNullNil(((Node)yyVals[-1+yyTop]));

yyVal = new DefnNode(((ISourcePosition)yyVals[-5+yyTop]), ((String)yyVals[-4+yyTop]), (ArgsNode) yyVals[-2+yyTop], support.getCurrentScope(), body, ((ISourcePosition)yyVals[0+yyTop]).getLine());
support.popCurrentScope();
Expand Down Expand Up @@ -4234,7 +4229,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
} else {
node = ((Node)yyVals[-1+yyTop]);
}
Node body = node == null ? NilImplicitNode.NIL : node;
Node body = support.makeNullNil(node);
yyVal = new RescueBodyNode(((ISourcePosition)yyVals[-5+yyTop]), ((Node)yyVals[-4+yyTop]), body, ((RescueBodyNode)yyVals[0+yyTop]));
return yyVal;
}
Expand Down Expand Up @@ -5347,7 +5342,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
}
};
}
// line 2575 "RubyParser.y"
// line 2570 "RubyParser.y"

/** The parse method use an lexer stream and parse it to an AST node
* structure
Expand All @@ -5362,4 +5357,4 @@ public RubyParserResult parse(ParserConfiguration configuration) throws IOExcept
return support.getResult();
}
}
// line 10131 "-"
// line 10126 "-"
31 changes: 13 additions & 18 deletions core/src/main/java/org/jruby/parser/RubyParser.y
Expand Up @@ -81,7 +81,6 @@ import org.jruby.ast.Node;
import org.jruby.ast.NonLocalControlFlowNode;
import org.jruby.ast.NumericNode;
import org.jruby.ast.OpAsgnAndNode;
import org.jruby.ast.OpAsgnNode;
import org.jruby.ast.OpAsgnOrNode;
import org.jruby.ast.OptArgNode;
import org.jruby.ast.PostExeNode;
Expand Down Expand Up @@ -116,11 +115,9 @@ import org.jruby.lexer.yacc.ISourcePositionHolder;
import org.jruby.lexer.LexerSource;
import org.jruby.lexer.yacc.RubyLexer;
import org.jruby.lexer.yacc.StrTerm;
import org.jruby.lexer.yacc.SyntaxException;
import org.jruby.lexer.yacc.SyntaxException.PID;
import org.jruby.util.ByteList;
import org.jruby.util.KeyValuePair;
import org.jruby.util.cli.Options;
import org.jruby.util.StringSupport;
import static org.jruby.lexer.LexingCommon.EXPR_BEG;
import static org.jruby.lexer.LexingCommon.EXPR_FITEM;
Expand Down Expand Up @@ -375,8 +372,7 @@ bodystmt : compstmt opt_rescue opt_else opt_ensure {
node = support.appendToBlock($1, $3);
}
if ($4 != null) {
if (node == null) node = NilImplicitNode.NIL;
node = new EnsureNode(support.getPosition($1), node, $4);
node = new EnsureNode(support.getPosition($1), support.makeNullNil(node), $4);
}

support.fixpos(node, $1);
Expand Down Expand Up @@ -408,7 +404,7 @@ stmt_or_begin : stmt {
| kBEGIN {
support.yyerror("BEGIN is permitted only at toplevel");
} tLCURLY top_compstmt tRCURLY {
$$ = new BeginNode($1, $2 == null ? NilImplicitNode.NIL : $2);
$$ = new BeginNode($1, support.makeNullNil($2));
}

stmt : kALIAS fitem {
Expand Down Expand Up @@ -1084,14 +1080,14 @@ arg : lhs '=' arg {
support.checkExpression($3);

boolean isLiteral = $1 instanceof FixnumNode && $3 instanceof FixnumNode;
$$ = new DotNode(support.getPosition($1), $1, $3, false, isLiteral);
$$ = new DotNode(support.getPosition($1), support.makeNullNil($1), support.makeNullNil($3), false, isLiteral);
}
| arg tDOT3 arg {
support.checkExpression($1);
support.checkExpression($3);

boolean isLiteral = $1 instanceof FixnumNode && $3 instanceof FixnumNode;
$$ = new DotNode(support.getPosition($1), $1, $3, true, isLiteral);
$$ = new DotNode(support.getPosition($1), support.makeNullNil($1), support.makeNullNil($3), true, isLiteral);
}
| arg tPLUS arg {
$$ = support.getOperatorCallNode($1, "+", $3, lexer.getPosition());
Expand Down Expand Up @@ -1195,7 +1191,7 @@ arg : lhs '=' arg {

arg_value : arg {
support.checkExpression($1);
$$ = $1 != null ? $1 : NilImplicitNode.NIL;
$$ = support.makeNullNil($1);
}

aref_args : none
Expand Down Expand Up @@ -1346,7 +1342,7 @@ primary : literal
lexer.getCmdArgumentState().reset();
} bodystmt kEND {
lexer.getCmdArgumentState().reset($<Long>2.longValue());
$$ = new BeginNode($1, $3 == null ? NilImplicitNode.NIL : $3);
$$ = new BeginNode($1, support.makeNullNil($3));
}
| tLPAREN_ARG {
lexer.setState(EXPR_ENDARG);
Expand Down Expand Up @@ -1436,15 +1432,15 @@ primary : literal
} expr_value do {
lexer.getConditionState().end();
} compstmt kEND {
Node body = $6 == null ? NilImplicitNode.NIL : $6;
Node body = support.makeNullNil($6);
$$ = new WhileNode($1, support.getConditionNode($3), body);
}
| kUNTIL {
lexer.getConditionState().begin();
} expr_value do {
lexer.getConditionState().end();
} compstmt kEND {
Node body = $6 == null ? NilImplicitNode.NIL : $6;
Node body = support.makeNullNil($6);
$$ = new UntilNode($1, support.getConditionNode($3), body);
}
| kCASE expr_value opt_terms case_body kEND {
Expand All @@ -1467,7 +1463,7 @@ primary : literal
}
support.pushLocalScope();
} bodystmt kEND {
Node body = $5 == null ? NilImplicitNode.NIL : $5;
Node body = support.makeNullNil($5);

$$ = new ClassNode($1, $<Colon3Node>2, support.getCurrentScope(), body, $3);
support.popCurrentScope();
Expand All @@ -1480,7 +1476,7 @@ primary : literal
support.setInSingle(0);
support.pushLocalScope();
} bodystmt kEND {
Node body = $7 == null ? NilImplicitNode.NIL : $7;
Node body = support.makeNullNil($7);

$$ = new SClassNode($1, $3, support.getCurrentScope(), body);
support.popCurrentScope();
Expand All @@ -1493,7 +1489,7 @@ primary : literal
}
support.pushLocalScope();
} bodystmt kEND {
Node body = $4 == null ? NilImplicitNode.NIL : $4;
Node body = support.makeNullNil($4);

$$ = new ModuleNode($1, $<Colon3Node>2, support.getCurrentScope(), body);
support.popCurrentScope();
Expand All @@ -1504,8 +1500,7 @@ primary : literal
$$ = lexer.getCurrentArg();
lexer.setCurrentArg(null);
} f_arglist bodystmt kEND {
Node body = $5;
if (body == null) body = NilImplicitNode.NIL;
Node body = support.makeNullNil($5);

$$ = new DefnNode($1, $2, (ArgsNode) $4, support.getCurrentScope(), body, $6.getLine());
support.popCurrentScope();
Expand Down Expand Up @@ -1849,7 +1844,7 @@ opt_rescue : kRESCUE exc_list exc_var then compstmt opt_rescue {
} else {
node = $5;
}
Node body = node == null ? NilImplicitNode.NIL : node;
Node body = support.makeNullNil(node);
$$ = new RescueBodyNode($1, $2, body, $6);
}
| {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/parser/skeleton.parser
Expand Up @@ -101,7 +101,7 @@ t
. /** the generated parser, with debugging messages.
. Maintains a dynamic state and value stack.
. @param yyLex scanner.
. @param yydebug debug message writer implementing <tt>yyDebug</tt>, or <tt>null</tt>.
. @param ayydebug debug message writer implementing <tt>yyDebug</tt>, or <tt>null</tt>.
. @return result of the last reduction, if any.
. */
. public Object yyparse (RubyLexer yyLex, Object ayydebug)
Expand Down
4 changes: 0 additions & 4 deletions test/mri/excludes/TestSyntax.rb
Expand Up @@ -11,7 +11,3 @@
exclude :test_duplicated_when, "needs investigation"
exclude :test_integer_suffix, "needs investigation"
exclude :test_invalid_next, "needs investigation"
exclude :test_null_range_cmdarg, "needs investigation"



0 comments on commit ffc235a

Please sign in to comment.