Fix java/tainted-arithmetic CodeQL alerts (#765)
| | |
| | | * of the underlying byte sequence. |
| | | */ |
| | | public void skip(final int length) { |
| | | position(pos + length); |
| | | final long newPos = (long) pos + length; |
| | | if (newPos < 0 || newPos > sequence.length()) { |
| | | throw new IndexOutOfBoundsException(); |
| | | } |
| | | position((int) newPos); |
| | | } |
| | | |
| | | @Override |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2012-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | |
| | | throw new LocalizedIllegalArgumentException(message); |
| | | } |
| | | |
| | | final Double fractionValue = Double.parseDouble(fractionBuffer.toString()); |
| | | final int additionalMilliseconds = (int) Math.round(fractionValue * multiplier); |
| | | final double fractionValue; |
| | | try { |
| | | fractionValue = Double.parseDouble(fractionBuffer.toString()); |
| | | } catch (final NumberFormatException e) { |
| | | final LocalizableMessage message = |
| | | WARN_ATTR_SYNTAX_GENERALIZED_TIME_ILLEGAL_TIME.get(value, fractionBuffer); |
| | | throw new LocalizedIllegalArgumentException(message, e); |
| | | } |
| | | if (fractionValue < 0.0d || fractionValue >= 1.0d) { |
| | | // "0." followed by 17 nines parses as exactly 1.0, so reject before scaling. |
| | | final LocalizableMessage message = |
| | | WARN_ATTR_SYNTAX_GENERALIZED_TIME_ILLEGAL_TIME.get(value, fractionBuffer); |
| | | throw new LocalizedIllegalArgumentException(message); |
| | | } |
| | | final long additionalMilliseconds = Math.round(fractionValue * multiplier); |
| | | if (additionalMilliseconds >= multiplier) { |
| | | // 16 nines: 0.9999999999999999 * 1000 still rounds up to 1000. The calendar below |
| | | // only validates lazily, so reject the out-of-range value here. |
| | | final LocalizableMessage message = |
| | | WARN_ATTR_SYNTAX_GENERALIZED_TIME_ILLEGAL_TIME.get(value, fractionBuffer); |
| | | throw new LocalizedIllegalArgumentException(message); |
| | | } |
| | | |
| | | try { |
| | | final GregorianCalendar calendar = new GregorianCalendar(); |
| | | calendar.setLenient(false); |
| | | calendar.setTimeZone(timeZone); |
| | | calendar.set(year, month, day, hour, minute, second); |
| | | calendar.set(Calendar.MILLISECOND, additionalMilliseconds); |
| | | calendar.set(Calendar.MILLISECOND, (int) additionalMilliseconds); |
| | | return new GeneralizedTime(calendar, null, Long.MIN_VALUE, value); |
| | | } catch (final Exception e) { |
| | | // This should only happen if the provided date wasn't legal |
| | |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014-2015 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | |
| | | reader.skip(1); |
| | | } |
| | | |
| | | @Test(dataProvider = "readerProvider", expectedExceptions = IndexOutOfBoundsException.class) |
| | | public void testSkipOverflow(ByteSequenceReader reader, byte[] ba) { |
| | | reader.rewind(); |
| | | reader.skip(ba.length); |
| | | // pos + Integer.MAX_VALUE overflows int; must throw, not wrap around. |
| | | reader.skip(Integer.MAX_VALUE); |
| | | } |
| | | |
| | | @Test(dataProvider = "readerProvider") |
| | | public void testPeek(ByteSequenceReader reader, byte[] ba) { |
| | | reader.rewind(); |
| | |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | * Portions copyright 2012-2015 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | |
| | | { "2006122a235959Z" }, { "20060031235959Z" }, { "20061331235959Z" }, |
| | | { "20062231235959Z" }, { "20061232235959Z" }, { "2006123123595aZ" }, |
| | | { "200a1231235959Z" }, { "2006j231235959Z" }, { "200612-1235959Z" }, |
| | | { "20061231#35959Z" }, { "2006" }, }; |
| | | { "20061231#35959Z" }, { "2006" }, |
| | | // Double.parseDouble rounds 17 nines up to exactly 1.0. |
| | | { "20240101000000.99999999999999999Z" }, |
| | | // 16 nines stay below 1.0 but scale and round to 1000 milliseconds. |
| | | { "20240101000000.9999999999999999Z" }, }; |
| | | } |
| | | |
| | | @Test |
| | |
| | | * |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013-2015 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.replication.common; |
| | | |
| | |
| | | } |
| | | else if (csn1.seqnum != csn2.seqnum) |
| | | { |
| | | return csn1.seqnum - csn2.seqnum; |
| | | return Integer.compare(csn1.seqnum, csn2.seqnum); |
| | | } |
| | | else |
| | | { |
| | | return csn1.serverId - csn2.serverId; |
| | | return Integer.compare(csn1.serverId, csn2.serverId); |
| | | } |
| | | } |
| | | |
| | |
| | | * |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.replication.common; |
| | | |
| | |
| | | @DataProvider(name = "createCSN") |
| | | public Object[][] createCSNData() |
| | | { |
| | | long time[] = {1, TimeThread.getTime()}; |
| | | int seq[] = {0, 123}; |
| | | int id [] = {1, 45}; |
| | | long time[] = {1, TimeThread.getTime(), 1, 1}; |
| | | int seq[] = {0, 123, Integer.MIN_VALUE, Integer.MAX_VALUE - 1}; |
| | | int id [] = {1, 45, 1, 1}; |
| | | |
| | | Object[][] obj = new Object[time.length][5]; |
| | | for (int i=0; i<time.length; i++) |
| | |
| | | assertTrue(CSN.compare(csn5, csn1) > 0); |
| | | } |
| | | |
| | | /** |
| | | * Test that {@link CSN#compare(CSN, CSN)} orders extreme seqnums correctly and |
| | | * transitively: subtraction-based comparison overflowed for MIN_VALUE vs |
| | | * MAX_VALUE at equal timestamps and inverted the sign, which is fatal for |
| | | * TreeMaps keyed on CSN. |
| | | */ |
| | | @Test |
| | | public void csnCompareExtremeSeqnums() throws Exception |
| | | { |
| | | final CSN minSeqnum = new CSN(1, Integer.MIN_VALUE, 1); |
| | | final CSN zeroSeqnum = new CSN(1, 0, 1); |
| | | final CSN maxSeqnum = new CSN(1, Integer.MAX_VALUE, 1); |
| | | |
| | | assertTrue(CSN.compare(minSeqnum, zeroSeqnum) < 0); |
| | | assertTrue(CSN.compare(zeroSeqnum, maxSeqnum) < 0); |
| | | assertTrue(CSN.compare(minSeqnum, maxSeqnum) < 0); |
| | | assertTrue(CSN.compare(maxSeqnum, minSeqnum) > 0); |
| | | assertEquals(CSN.compare(maxSeqnum, maxSeqnum), 0); |
| | | } |
| | | |
| | | /** Test {@link CSN#isOlderThan(CSN)} method. */ |
| | | @Test(dataProvider = "createCSN") |
| | | public void csnOlder(CSN csn1, CSN csn2, CSN csn3, CSN csn4, CSN csn5) throws Exception |