Skip to content
Snippets Groups Projects
Commit 0eb7f440 authored by Tomas Stupka's avatar Tomas Stupka
Browse files

prevent negative indices in Collections.NonRecursiveHashSetDouble

parent 4a428bd6
Branches
No related tags found
No related merge requests found
/*
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -92,7 +92,7 @@ public final class Collections {
}
public boolean add(double key) {
int ind = Math.abs(Double.hashCode(key)) % keys.length;
int ind = getInd(key, keys.length);
int firstInd = ind;
while (true) {
if (RRuntime.isNAorNaN(keys[ind])) {
......@@ -108,7 +108,7 @@ public final class Collections {
Arrays.fill(newKeys, RRuntime.DOUBLE_NA);
for (int i = 0; i < keys.length; i++) {
if (!RRuntime.isNAorNaN(keys[i])) {
int tmpInd = Math.abs(Double.hashCode(keys[i])) % newKeys.length;
int tmpInd = getInd(keys[i], newKeys.length);
while (true) {
if (RRuntime.isNAorNaN(newKeys[tmpInd])) {
newKeys[tmpInd] = keys[i];
......@@ -124,11 +124,22 @@ public final class Collections {
keys = newKeys;
// start hashing from the beginning
ind = Math.abs(Double.hashCode(key)) % keys.length;
ind = getInd(key, keys.length);
}
}
}
}
private static int getInd(double key, int keyLength) {
int h = Double.hashCode(key);
if (h == Integer.MIN_VALUE) {
// HOTFIX:
// Double.hashCode(-0.0) is Integer.MIN_VALUE
// Maths.abs(Integer.MIN_VALUE) is Integer.MIN_VALUE
return 0;
}
return Math.abs(h) % keyLength;
}
}
public static class NonRecursiveHashSetInt {
......
......@@ -4,7 +4,7 @@
* http://www.gnu.org/licenses/gpl-2.0.html
*
* Copyright (c) 2012-2014, Purdue University
* Copyright (c) 2013, 2017, Oracle and/or its affiliates
* Copyright (c) 2013, 2018, Oracle and/or its affiliates
*
* All rights reserved.
*/
......@@ -192,5 +192,7 @@ public class TestBuiltin_unique extends TestBase {
// seems a bit better than GnuR's "cannot coerce type 'closure' to vector of type 'double'"
assertEval(Ignored.ReferenceError, "{ unique(c(1,2,1), incomparables=function() 42) }");
assertEval("{ unique(c(-0.0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)) }");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment