Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7b964fd
Update stdlib to Ruby 2.5.3.
headius Dec 10, 2018
0e23fb9
Update tests from MRI 2.5 branch (2.4ish)
headius Dec 10, 2018
c6f87ce
Restore workaround for __method__.
headius Dec 10, 2018
7b66187
Taint ARGV values.
headius Dec 10, 2018
1797cfc
Exclude test of InstructionSequence.
headius Dec 10, 2018
405bc50
Check step comparison result for nil and normalize to -1, 0, 1.
headius Dec 10, 2018
912faae
Check UNIXSocket path for nulls.
headius Dec 10, 2018
0be4003
Exclude test that's likey the same thing as #4531.
headius Dec 10, 2018
4563cab
Check for NaN and Inf in Array/Enumerable#sum.
headius Dec 10, 2018
b46645a
Tag this and fix as part of #5489.
headius Dec 10, 2018
45e988b
Check all paths for embedded nulls.
headius Dec 10, 2018
84019af
zsuper can have any argument changed between original params and when…
enebo Dec 10, 2018
f19cf7c
END blocks can contain return and break. We catch the somewhat weird
enebo Dec 10, 2018
a8b844c
Fix NameError's receiver for private constant error.
headius Dec 11, 2018
64d9fae
Fixes error where String#each_line was doing an extra chomp of a newl…
enebo Dec 11, 2018
993acbc
Render top-level warnings above the root script frame like MRI.
headius Dec 11, 2018
373b3ab
Pull back on String#each_grapheme allowing single byte optimizable path
enebo Dec 11, 2018
078c210
Fix some javadoc errors
enebo Dec 11, 2018
d6a8535
Exclude Pack test for buffer overrun that fails differently.
headius Dec 11, 2018
46379fe
Localize memo to the yielder, not the Lazy.
headius Dec 11, 2018
abe5c19
Support key swapping in Hash#transform_keys!.
headius Dec 11, 2018
6ee831b
Fixable but several method signatures needs to change and other stuff…
enebo Dec 12, 2018
a73835d
Grapheme clusters make sub strings out of main string and need to pro…
enebo Dec 12, 2018
fcb6cdb
Exclude tests and specs for reverse or highlighted MRI trace.
headius Dec 12, 2018
65355e1
Raise for uplevel less than zero.
headius Dec 13, 2018
58d5a2e
Additional work deferred to #5510.
headius Dec 13, 2018
14e8a85
Tag Pack infection spec for same reasons as 6ee831b9418.
headius Dec 13, 2018
7ef7efb
Restore TestPack#test_unpack_atmark test exclude.
headius Dec 13, 2018
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
6 changes: 3 additions & 3 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ DO NOT MODIFIY - GENERATED CODE
<test.results.dir>${build.dir}/test-results</test.results.dir>
<tzdata.scope>provided</tzdata.scope>
<tzdata.version>2013d</tzdata.version>
<version.ruby>2.5.0</version.ruby>
<version.ruby>2.5.3</version.ruby>
<version.ruby.major>2.5</version.ruby.major>
<version.ruby.minor>0</version.ruby.minor>
<version.ruby.revision>60928</version.ruby.revision>
<version.ruby.minor>3</version.ruby.minor>
<version.ruby.revision>66309</version.ruby.revision>
</properties>
<dependencies>
<dependency>
Expand Down
11 changes: 11 additions & 0 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import org.jruby.ir.IRScope;
import org.jruby.ir.IRScriptBody;
import org.jruby.ir.instructions.Instr;
import org.jruby.ir.runtime.IRWrappedLambdaReturnValue;
import org.jruby.javasupport.JavaSupport;
import org.jruby.javasupport.JavaSupportImpl;
import org.jruby.lexer.yacc.ISourcePosition;
Expand Down Expand Up @@ -3325,6 +3326,16 @@ public void tearDown(boolean systemExit) {
}
// Reset $! now that rj has been handled
// context.runtime.getGlobalVariables().set("$!", oldExc);
} catch (IRWrappedLambdaReturnValue e) {
// This is partially similar to code in eval_error.c:error_handle but with less actual cases.
// IR treats END blocks are closures and as such we see this special non-local return jump type
// bubble this far out as we exec each END proc.
String filename = proc.getBlock().getBinding().filename;
if (e.isReturn()) {
getWarnings().warn(filename, "unexpected return");
} else {
getWarnings().warn(filename, "break from proc-closure");
}
}
}

Expand Down
15 changes: 15 additions & 0 deletions core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -4669,6 +4669,21 @@ public IRubyObject sumCommon(final ThreadContext context, IRubyObject init, fina
} else {
break float_loop;
}

if (Double.isNaN(f)) continue;
if (Double.isNaN(x)) {
f = x;
continue;
}
if (Double.isInfinite(x)) {
if (Double.isInfinite(f) && Math.signum(x) != Math.signum(f))
f = Double.NaN;
else
f = x;
continue;
}
if (Double.isInfinite(f)) continue;

t = f + x;
if (Math.abs(f) >= Math.abs(x)) {
c += ((f - t) + x);
Expand Down
11 changes: 11 additions & 0 deletions core/src/main/java/org/jruby/RubyBasicObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -2178,6 +2178,17 @@ public IRubyObject taint(ThreadContext context) {
return this;
}

/**
* Set the object tainted and return it. This version does not check if the object has been frozen or if it is
* already tainted.
*
* @return
*/
IRubyObject tainted() {
setTaint(true);
return this;
}

@Deprecated
protected final void taint(Ruby runtime) {
taint(runtime.getCurrentContext());
Expand Down
17 changes: 16 additions & 1 deletion core/src/main/java/org/jruby/RubyEnumerable.java
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,21 @@ public static IRubyObject sumAdd(final ThreadContext ctx, IRubyObject lhs, IRuby
return lhs.callMethod(ctx, "+", rhs);
}

Ruby runtime = ctx.runtime;

if (Double.isNaN(f)) return lhs;
if (Double.isNaN(x)) {
return lhs;
}
if (Double.isInfinite(x)) {
if (Double.isInfinite(f) && Math.signum(x) != Math.signum(f)) {
return new RubyFloat(runtime, RubyFloat.NAN);
} else {
return rhs;
}
}
if (Double.isInfinite(f)) return lhs;

// Kahan's compensated summation algorithm
t = f + x;
if (Math.abs(f) >= Math.abs(x)) {
Expand All @@ -1016,7 +1031,7 @@ public static IRubyObject sumAdd(final ThreadContext ctx, IRubyObject lhs, IRuby
}
f = t;

return new RubyFloat(ctx.runtime, f);
return new RubyFloat(runtime, f);
}

public static IRubyObject injectCommon(final ThreadContext context, IRubyObject self, IRubyObject init, final Block block) {
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/RubyFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -1475,7 +1475,7 @@ public IRubyObject fileOpenGeneric(ThreadContext context, IRubyObject filename,

// mri: FilePathValue/rb_get_path/rb_get_patch_check
public static RubyString get_path(ThreadContext context, IRubyObject path) {
if (path instanceof RubyString) return (RubyString) path;
if (path instanceof RubyString) return StringSupport.checkEmbeddedNulls(context.runtime, path);

FileSites sites = sites(context);
if (sites.respond_to_to_path.respondsTo(context, path, path, true)) path = sites.to_path.call(context, path, path);
Expand All @@ -1486,6 +1486,8 @@ public static RubyString get_path(ThreadContext context, IRubyObject path) {
// FIXME: MRI skips this logic on windows? Does not make sense to me why so I left it in.
// mri: file_path_convert
private static RubyString filePathConvert(ThreadContext context, RubyString path) {
StringSupport.checkEmbeddedNulls(context.runtime, path.convertToString());

if (!Platform.IS_WINDOWS) {
Ruby runtime = context.getRuntime();
EncodingService encodingService = runtime.getEncodingService();
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyGlobal.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public static void initARGV(Ruby runtime) {
String[] argv = runtime.getInstanceConfig().getArgv();

for (String arg : argv) {
argvArray.append(RubyString.newInternalFromJavaExternal(runtime, arg));
argvArray.append(RubyString.newInternalFromJavaExternal(runtime, arg).tainted());
}

if (runtime.getObject().getConstantNoConstMissing("ARGV") != null) {
Expand Down
12 changes: 8 additions & 4 deletions core/src/main/java/org/jruby/RubyHash.java
Original file line number Diff line number Diff line change
Expand Up @@ -1515,10 +1515,14 @@ public IRubyObject transform_values(final ThreadContext context, final Block blo
public IRubyObject transform_keys_bang(final ThreadContext context, final Block block) {
if (block.isGiven()) {
testFrozen("Hash");
RubyArray keys = keys(context);
Arrays.stream(keys.toJavaArrayMaybeUnsafe()).forEach((key) -> {
op_aset(context, block.yield(context, key), delete(context, key));
});
RubyArray pairs = (RubyArray) flatten(context);
clear();
for (int i = 0; i < pairs.size(); i += 2) {
IRubyObject key = pairs.eltOk(i);
IRubyObject newKey = block.yield(context, key);
IRubyObject value = pairs.eltOk(i + 1);
op_aset(context, newKey, value);
}
return this;
}

Expand Down
6 changes: 5 additions & 1 deletion core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
Expand Up @@ -1258,14 +1258,18 @@ static IRubyObject warn(ThreadContext context, IRubyObject recv, RubyString mess
@JRubyMethod(module = true, rest = true, visibility = PRIVATE)
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
boolean kwargs = false;
int uplevel = -1;
int uplevel = 0;

if (args.length > 1) {
IRubyObject tmp = TypeConverter.checkHashType(context.runtime, args[args.length - 1]);
if (tmp != context.nil) {
kwargs = true;
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) tmp, WARN_VALID_KEYS);
uplevel = rets[0] == UNDEF ? 0 : RubyNumeric.num2int(rets[0]);

if (uplevel < 0) {
throw context.runtime.newArgumentError("negative level (" + uplevel + ")");
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -4384,7 +4384,9 @@ public IRubyObject fetchConstant(String name, boolean includePrivate) {
if (entry == null) return null;

if (entry.hidden && !includePrivate) {
throw getRuntime().newNameError("private constant " + getName() + "::" + name + " referenced", name);
RubyModule recv = this;
if (recv.isIncluded()) recv = recv.getNonIncludedClass();
throw getRuntime().newNameError("private constant " + getName() + "::" + name + " referenced", recv, name);
}
if (entry.deprecated) {
final Ruby runtime = getRuntime();
Expand Down
7 changes: 5 additions & 2 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
Expand Up @@ -5711,6 +5711,7 @@ else if (!wantarray) {
for (int i = 0; i < len; i += n) {
n = StringSupport.encFastMBCLen(ptrBytes, ptr + i, ptr + len, enc);
IRubyObject substr = str.substr(runtime, i, n);
substr.infectBy(str);
if (wantarray) ary[a++] = substr;
else block.yield(context, substr);
}
Expand All @@ -5719,6 +5720,7 @@ else if (!wantarray) {
for (int i = 0; i < len; i += n) {
n = StringSupport.length(enc, ptrBytes, ptr + i, ptr + len);
IRubyObject substr = str.substr(runtime, i, n);
substr.infectBy(str);
if (wantarray) ary[a++] = substr;
else block.yield(context, substr);
}
Expand Down Expand Up @@ -5811,7 +5813,7 @@ public IRubyObject size(IRubyObject[] args) {
Ruby runtime = getRuntime();
ByteList value = getByteList();
Encoding enc = value.getEncoding();
if (!enc.isUnicode() || isSingleByteOptimizable(RubyString.this, enc)) return rubyLength(runtime);
if (!enc.isUnicode()) return rubyLength(runtime);

Regex reg = RubyRegexp.getRegexpFromCache(runtime, GRAPHEME_CLUSTER_PATTERN, enc, RegexpOptions.NULL_OPTIONS);
int beg = value.getBegin();
Expand All @@ -5834,7 +5836,7 @@ private IRubyObject enumerateGraphemeClusters(ThreadContext context, String name
Ruby runtime = context.runtime;
RubyString str = this;
Encoding enc = str.getEncoding();
if (!enc.isUnicode() || isSingleByteOptimizable(str, enc)) {
if (!enc.isUnicode()) {
return enumerateChars(context, name, block, wantarray);
}

Expand Down Expand Up @@ -5863,6 +5865,7 @@ else if (!wantarray) {
int len = matcher.match(ptr, end, Option.DEFAULT);
if (len <= 0) break;
RubyString result = newStringShared(runtime, ptrBytes, ptr, len, enc);
result.infectBy(str);
if (wantarray) ary.append(result);
else block.yield(context, result);
ptr += len;
Expand Down
11 changes: 11 additions & 0 deletions core/src/main/java/org/jruby/common/RubyWarnings.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,17 @@ public void warn(ID id, String message) {
warn(id, file, line - 1, message);
}

public void warn(String filename, String message) {
if (!runtime.warningsEnabled()) return;

StringBuilder buffer = new StringBuilder(100);

buffer.append(filename).append(": ").append(message).append('\n');
RubyString errorString = runtime.newString(buffer.toString());

writeWarningDyncall(runtime.getCurrentContext(), errorString);
}

public void warnOnce(ID id, String message) {
if (!runtime.warningsEnabled()) return;
if (oncelers.contains(id)) return;
Expand Down
10 changes: 9 additions & 1 deletion core/src/main/java/org/jruby/ext/socket/RubyUNIXSocket.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;
import org.jruby.util.io.ModeFlags;
import org.jruby.util.io.OpenFile;
import org.jruby.util.io.FilenoUtil;
Expand Down Expand Up @@ -327,7 +328,8 @@ protected static void rb_sys_fail(Ruby runtime, String message) {
}

protected void init_unixsock(Ruby runtime, IRubyObject _path, boolean server) {
ByteList path = _path.convertToString().getByteList();
RubyString strPath = unixsockPathValue(runtime, _path);
ByteList path = strPath.getByteList();
String fpath = Helpers.decodeByteList(runtime, path);

int maxSize = 103; // Max size from Darwin, lowest common value we know of
Expand Down Expand Up @@ -366,6 +368,12 @@ protected void init_unixsock(Ruby runtime, IRubyObject _path, boolean server) {
}
}

// MRI: unixsock_path_value
private static RubyString unixsockPathValue(Ruby runtime, IRubyObject path) {
return StringSupport.checkEmbeddedNulls(runtime, path.convertToString());
}


protected void init_sock(Ruby runtime, Channel channel, String path) {
MakeOpenFile();

Expand Down
7 changes: 4 additions & 3 deletions core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ private static IRScopeType ensureScopeIsClosure(ThreadContext context, DynamicSc
public static IRubyObject initiateBreak(ThreadContext context, DynamicScope dynScope, IRubyObject breakValue, Block block) throws RuntimeException {
// Wrap the return value in an exception object and push it through the break exception
// paths so that ensures are run, frames/scopes are popped from runtime stacks, etc.
if (inLambda(block.type)) throw new IRWrappedLambdaReturnValue(breakValue);
if (inLambda(block.type)) throw new IRWrappedLambdaReturnValue(breakValue, true);

IRScopeType scopeType = ensureScopeIsClosure(context, dynScope);

Expand Down Expand Up @@ -1168,13 +1168,14 @@ public static IRubyObject[] splatArguments(IRubyObject[] args, boolean[] splatMa
if (splatMap != null && splatMap.length > 0) {
int count = 0;
for (int i = 0; i < splatMap.length; i++) {
count += splatMap[i] ? ((RubyArray)args[i]).size() : 1;
// make sure arg is still an array (zsuper can get have any args changed before it is called).
count += splatMap[i] && args[i] instanceof RubyArray ? ((RubyArray)args[i]).size() : 1;
}

IRubyObject[] newArgs = new IRubyObject[count];
int actualOffset = 0;
for (int i = 0; i < splatMap.length; i++) {
if (splatMap[i]) {
if (splatMap[i] && args[i] instanceof RubyArray) {
RubyArray ary = (RubyArray) args[i];
for (int j = 0; j < ary.size(); j++) {
newArgs[actualOffset++] = ary.eltOk(j);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,18 @@
// are updated properly and ruby-level ensure code is run.
public class IRWrappedLambdaReturnValue extends IRJump implements Unrescuable {
public final IRubyObject returnValue;
boolean isBreak;

public IRWrappedLambdaReturnValue(IRubyObject v) {
public IRWrappedLambdaReturnValue(IRubyObject v, boolean isBreak) {
this.returnValue = v;
this.isBreak = isBreak;
}

public IRWrappedLambdaReturnValue(IRubyObject v) {
this(v, false);
}

public boolean isReturn() {
return !isBreak;
}
}
12 changes: 7 additions & 5 deletions core/src/main/java/org/jruby/util/Pack.java
Original file line number Diff line number Diff line change
Expand Up @@ -491,13 +491,15 @@ public static void encodeUM(Ruby runtime, ByteList lCurElemString, int occurrenc
* encodes a String in base64 or its uuencode variant.
* appends the result of the encoding in a StringBuffer
* @param io2Append The StringBuffer which should receive the result
* @param i2Encode The String to encode
* @param iLength The max number of characters to encode
* @param iType the type of encoding required (this is the same type as used by the pack method)
* @param charsToEncode The String to encode
* @param startIndex
* @param length The max number of characters to encode
* @param charCount
* @param encodingType the type of encoding required (this is the same type as used by the pack method)
* @param tailLf true if the traililng "\n" is needed
* @return the io2Append buffer
**/
private static ByteList encodes(Ruby runtime, ByteList io2Append,byte[]charsToEncode, int startIndex, int length, int charCount, byte encodingType, boolean tailLf) {
private static ByteList encodes(Ruby runtime, ByteList io2Append,byte[] charsToEncode, int startIndex, int length, int charCount, byte encodingType, boolean tailLf) {
charCount = charCount < length ? charCount : length;

io2Append.ensure(charCount * 4 / 3 + 6);
Expand Down Expand Up @@ -550,7 +552,7 @@ public static RubyArray unpack(Ruby runtime, ByteList encodedString, ByteList fo
}

/**
* @see #unpackWithBlock(ThreadContext, RubyString, ByteList, Block)
* @see Pack#unpackWithBlock(ThreadContext, Ruby, ByteList, ByteList, Block)
* @param context
* @param encoded
* @param formatString
Expand Down
10 changes: 6 additions & 4 deletions core/src/main/java/org/jruby/util/StringSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -1964,10 +1964,12 @@ else if (!wantarray) {

if (subptr != pend) {
if (chomp) {
pend = chomp_newline(strBytes, subptr, pend, enc);
} else if (pend - subptr >= rslen &&
ByteList.memcmp(strBytes, pend - rslen, rsbytes, rsptr, rslen) == 0) {
pend -= rslen;
if (rsnewline) {
pend = chomp_newline(strBytes, subptr, pend, enc);
} else if (pend - subptr >= rslen &&
ByteList.memcmp(strBytes, pend - rslen, rsbytes, rsptr, rslen) == 0) {
pend -= rslen;
}
}
line = str.substr(runtime, subptr - ptr, pend - subptr);
if (wantarray) ary.append(line);
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/ruby/jruby/kernel/enumerator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,17 @@ def zip(*args)
end

def uniq
hash = {}
if block_given?
Lazy.new(self) do |yielder, obj|
hash = yielder.backports_memo ||= {}
ret = yield(*obj)
next if hash.key? ret
hash[ret] = obj
yielder << obj
end
else
Lazy.new(self) do |yielder, obj|
hash = yielder.backports_memo ||= {}
next if hash.key? obj
hash[obj] = obj unless hash.key? obj
yielder << obj
Expand Down
6 changes: 3 additions & 3 deletions default.build.properties
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ rake.args=
install4j.executable=/Applications/install4j7/bin/install4jc

# Ruby versions
version.ruby=2.5.0
version.ruby=2.5.3
version.ruby.major=2.5
version.ruby.minor=0
version.ruby.revision=60928
version.ruby.minor=3
version.ruby.revision=66309
Loading