8079841: Buffer underflow with empty zip entry names
Summary: check for zero-length entry name before accessing "last" byte
Reviewed-by: sherman, martin
/*
* Copyright (c) 2015 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8035712: Restore some of the RuntimeCallSite specializations
*
* @test
* @run
*/
if ((typeof Assert) == "undefined") {
Assert = {
assertTrue: function(x) { if(!x) { throw "expected true" } },
assertFalse: function(x) { if(x) { throw "expected false" } },
};
}
function nop() {}
function EQ(x, y) {
// Exercise normal evaluation
Assert.assertTrue (x == y);
Assert.assertTrue (y == x);
Assert.assertFalse(x != y);
Assert.assertFalse(y != x);
// Exercise the branch optimizer
if (x == y) { nop(); } else { Assert.fail(); }
if (y == x) { nop(); } else { Assert.fail(); }
if (x != y) { Assert.fail(); } else { nop(); }
if (y != x) { Assert.fail(); } else { nop(); }
}
function NE(x, y) {
// Exercise normal evaluation
Assert.assertTrue (x != y);
Assert.assertTrue (y != x);
Assert.assertFalse(x == y);
Assert.assertFalse(y == x);
// Exercise the branch optimizer
if (x != y) { nop(); } else { Assert.fail(); }
if (y != x) { nop(); } else { Assert.fail(); }
if (x == y) { Assert.fail(); } else { nop(); }
if (y == x) { Assert.fail(); } else { nop(); }
}
function STRICT_EQ(x, y) {
// Exercise normal evaluation
Assert.assertTrue (x === y);
Assert.assertTrue (y === x);
Assert.assertFalse(x !== y);
Assert.assertFalse(y !== x);
// Exercise the branch optimizer
if (x === y) { nop(); } else { Assert.fail(); }
if (y === x) { nop(); } else { Assert.fail(); }
if (x !== y) { Assert.fail(); } else { nop(); }
if (y !== x) { Assert.fail(); } else { nop(); }
}
function STRICT_NE(x, y) {
// Exercise normal evaluation
Assert.assertTrue (x !== y);
Assert.assertTrue (y !== x);
Assert.assertFalse(x === y);
Assert.assertFalse(y === x);
// Exercise the branch optimizer
if (x !== y) { nop(); } else { Assert.fail(); }
if (y !== x) { nop(); } else { Assert.fail(); }
if (x === y) { Assert.fail(); } else { nop(); }
if (y === x) { Assert.fail(); } else { nop(); }
}
function cmpToAnyNumber(cmp, value) {
cmp(1, value);
cmp(4294967296, value);
cmp(1.2, value);
cmp(Infinity, value);
cmp(-Infinity, value);
cmp(1/Infinity, value);
cmp(0, value);
cmp(-0, value);
cmp(true, value);
cmp(false, value);
}
function notEqualToAnyNumber(value) {
cmpToAnyNumber(NE, value);
cmpToAnyNumber(STRICT_NE, value);
}
notEqualToAnyNumber(null);
notEqualToAnyNumber(void 0);
notEqualToAnyNumber("abc");
notEqualToAnyNumber({});
notEqualToAnyNumber(["xyz"]);
function objectWithPrimitiveFunctionNotEqualToAnyNumber(fnName) {
var obj = {
count: 0
};
obj[fnName] = function() { this.count++; return "foo"; };
notEqualToAnyNumber(obj);
// Every NE will invoke it 8 times; cmpToAnyNumber has 10 comparisons
// STRICT_NE doesn't invoke toString.
Assert.assertTrue(80 === obj.count);
}
objectWithPrimitiveFunctionNotEqualToAnyNumber("valueOf");
objectWithPrimitiveFunctionNotEqualToAnyNumber("toString");
function objectEqualButNotStrictlyEqual(val, obj) {
EQ(val, obj);
STRICT_NE(val, obj);
}
function numberEqualButNotStrictlyEqualToObject(num, obj) {
objectEqualButNotStrictlyEqual(num, obj);
objectEqualButNotStrictlyEqual(num, [obj]);
objectEqualButNotStrictlyEqual(num, [[obj]]);
}
function numberEqualButNotStrictlyEqualToZeroObjects(num) {
numberEqualButNotStrictlyEqualToObject(num, [0]);
numberEqualButNotStrictlyEqualToObject(num, "");
numberEqualButNotStrictlyEqualToObject(num, []);
numberEqualButNotStrictlyEqualToObject(num, "0");
}
numberEqualButNotStrictlyEqualToZeroObjects(0);
numberEqualButNotStrictlyEqualToZeroObjects(1/Infinity);
numberEqualButNotStrictlyEqualToZeroObjects(false);
function numberEqualButNotStrictlyEqualToObjectEquivalent(num) {
var str = String(num);
objectEqualButNotStrictlyEqual(num, str);
objectEqualButNotStrictlyEqual(num, { valueOf: function() { return str }});
objectEqualButNotStrictlyEqual(num, { toString: function() { return str }});
objectEqualButNotStrictlyEqual(num, { valueOf: function() { return num }});
objectEqualButNotStrictlyEqual(num, { toString: function() { return num }});
}
numberEqualButNotStrictlyEqualToObjectEquivalent(1);
numberEqualButNotStrictlyEqualToObjectEquivalent(4294967296);
numberEqualButNotStrictlyEqualToObjectEquivalent(1.2);
numberEqualButNotStrictlyEqualToObjectEquivalent(Infinity);
numberEqualButNotStrictlyEqualToObjectEquivalent(-Infinity);
numberEqualButNotStrictlyEqualToObjectEquivalent(1/Infinity);
numberEqualButNotStrictlyEqualToObjectEquivalent(0);
numberEqualButNotStrictlyEqualToObjectEquivalent(-0);
STRICT_EQ(1, new java.lang.Integer(1));
STRICT_EQ(1, new java.lang.Double(1));
STRICT_EQ(1.2, new java.lang.Double(1.2));
function LE(x, y) {
// Exercise normal evaluation
Assert.assertTrue(x <= y);
Assert.assertTrue(y >= x);
Assert.assertFalse(x > y);
Assert.assertFalse(x < y);
// Exercise the branch optimizer
if (x <= y) { nop(); } else { Assert.fail(); }
if (y >= x) { nop(); } else { Assert.fail(); }
if (x > y) { Assert.fail(); } else { nop(); }
if (y < x) { Assert.fail(); } else { nop(); }
}
function mutuallyLessThanOrEqual(x, y) {
LE(x, y);
LE(y, x);
}
mutuallyLessThanOrEqual(0, null);
mutuallyLessThanOrEqual(false, null);
mutuallyLessThanOrEqual(1/Infinity, null);
function mutuallyLessThanEqualToObjectWithValue(num, val) {
mutuallyLessThanOrEqual(num, { valueOf: function() { return val } });
mutuallyLessThanOrEqual(num, { toString: function() { return val } });
}
mutuallyLessThanEqualToObjectWithValue(false, 0);
mutuallyLessThanEqualToObjectWithValue(false, "");
mutuallyLessThanEqualToObjectWithValue(true, 1);
mutuallyLessThanEqualToObjectWithValue(true, "1");
function lessThanEqualToObjectEquivalent(num) {
var str = String(num);
mutuallyLessThanOrEqual(num, str);
mutuallyLessThanEqualToObjectWithValue(num, num);
mutuallyLessThanEqualToObjectWithValue(num, str);
}
lessThanEqualToObjectEquivalent(1);
lessThanEqualToObjectEquivalent(4294967296);
lessThanEqualToObjectEquivalent(1.2);
lessThanEqualToObjectEquivalent(Infinity);
lessThanEqualToObjectEquivalent(-Infinity);
lessThanEqualToObjectEquivalent(1/Infinity);
lessThanEqualToObjectEquivalent(0);
lessThanEqualToObjectEquivalent(-0);
function INCOMPARABLE(x, y) {
// Exercise normal evaluation
Assert.assertFalse(x < y);
Assert.assertFalse(x > y);
Assert.assertFalse(x <= y);
Assert.assertFalse(x >= y);
Assert.assertFalse(y < x);
Assert.assertFalse(y > x);
Assert.assertFalse(y <= x);
Assert.assertFalse(y >= x);
// Exercise the branch optimizer
if (x < y) { Assert.fail(); } else { nop(); }
if (x > y) { Assert.fail(); } else { nop(); }
if (x <= y) { Assert.fail(); } else { nop(); }
if (x >= y) { Assert.fail(); } else { nop(); }
if (y < x) { Assert.fail(); } else { nop(); }
if (y > x) { Assert.fail(); } else { nop(); }
if (y <= x) { Assert.fail(); } else { nop(); }
if (y >= x) { Assert.fail(); } else { nop(); }
}
function isIncomparable(value) {
cmpToAnyNumber(INCOMPARABLE, value);
}
isIncomparable(void 0);
isIncomparable({ valueOf: function() { return NaN }});
isIncomparable({ toString: function() { return NaN }});
// Force ScriptRuntime.LT(Object, Object) etc. comparisons
function cmpObj(fn, x, y) {
fn({valueOf: function() { return x }}, {valueOf: function() { return y }});
}
function LT(x, y) {
Assert.assertTrue(x < y);
Assert.assertTrue(y > x);
Assert.assertFalse(x >= y);
Assert.assertFalse(y <= x);
}
cmpObj(LT, 1, 2);
cmpObj(LT, 1, "2");
cmpObj(LT, "1", 2);
cmpObj(LT, "a", "b");
cmpObj(LT, -Infinity, 0);
cmpObj(LT, 0, Infinity);
cmpObj(LT, -Infinity, Infinity);
cmpObj(INCOMPARABLE, 1, NaN);
cmpObj(INCOMPARABLE, NaN, NaN);
cmpObj(INCOMPARABLE, "boo", NaN);
cmpObj(INCOMPARABLE, 1, "boo"); // boo number value will be NaN
// Test that a comparison call site can deoptimize from (int, int) to (object, object)
(function(){
var x = [1, 2, "a"];
var y = [2, "3", "b"];
for(var i = 0; i < 3; ++i) {
Assert.assertTrue(x[i] < y[i]);
}
})();