mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
5041655: (ch) FileLock: negative param and overflow issues
Reviewed-by: alanb
This commit is contained in:
parent
7feabee426
commit
6445ee46b5
9 changed files with 247 additions and 45 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2022, 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
|
||||
|
@ -425,10 +425,13 @@ public abstract class AsynchronousFileChannel
|
|||
* required then a region starting at zero, and no smaller than the
|
||||
* expected maximum size of the file, should be locked. The two-argument
|
||||
* {@link #lock(Object,CompletionHandler)} method simply locks a region
|
||||
* of size {@link Long#MAX_VALUE}. If a lock that overlaps the requested
|
||||
* region is already held by this Java virtual machine, or this method has
|
||||
* been invoked to lock an overlapping region and that operation has not
|
||||
* completed, then this method throws {@link OverlappingFileLockException}.
|
||||
* of size {@link Long#MAX_VALUE}. If the {@code position} is non-negative
|
||||
* and the {@code size} is zero, then a lock of size
|
||||
* {@code Long.MAX_VALUE - position} is returned. If a lock that
|
||||
* overlaps the requested region is already held by this Java virtual
|
||||
* machine, or this method has been invoked to lock an overlapping region
|
||||
* and that operation has not completed, then this method throws
|
||||
* {@link OverlappingFileLockException}.
|
||||
*
|
||||
* <p> Some operating systems do not support a mechanism to acquire a file
|
||||
* lock in an asynchronous manner. Consequently an implementation may
|
||||
|
@ -454,7 +457,10 @@ public abstract class AsynchronousFileChannel
|
|||
* non-negative
|
||||
* @param size
|
||||
* The size of the locked region; must be non-negative, and the sum
|
||||
* {@code position} + {@code size} must be non-negative
|
||||
* {@code position} + {@code size} must be non-negative.
|
||||
* A value of zero means to lock all bytes from the specified
|
||||
* starting position to the end of the file, regardless of whether
|
||||
* the file is subsequently extended or truncated
|
||||
* @param shared
|
||||
* {@code true} to request a shared lock, in which case this
|
||||
* channel must be open for reading (and possibly writing);
|
||||
|
@ -532,7 +538,10 @@ public abstract class AsynchronousFileChannel
|
|||
* non-negative
|
||||
* @param size
|
||||
* The size of the locked region; must be non-negative, and the sum
|
||||
* {@code position} + {@code size} must be non-negative
|
||||
* {@code position} + {@code size} must be non-negative.
|
||||
* A value of zero means to lock all bytes from the specified
|
||||
* starting position to the end of the file, regardless of whether
|
||||
* the file is subsequently extended or truncated
|
||||
* @param shared
|
||||
* {@code true} to request a shared lock, in which case this
|
||||
* channel must be open for reading (and possibly writing);
|
||||
|
@ -586,7 +595,9 @@ public abstract class AsynchronousFileChannel
|
|||
* either having acquired a lock on the requested region or having failed to
|
||||
* do so. If it fails to acquire a lock because an overlapping lock is held
|
||||
* by another program then it returns {@code null}. If it fails to acquire
|
||||
* a lock for any other reason then an appropriate exception is thrown.
|
||||
* a lock for any other reason then an appropriate exception is thrown. If
|
||||
* the {@code position} is non-negative and the {@code size} is zero, then a
|
||||
* lock of size {@code Long.MAX_VALUE - position} is returned.
|
||||
*
|
||||
* @param position
|
||||
* The position at which the locked region is to start; must be
|
||||
|
@ -594,7 +605,10 @@ public abstract class AsynchronousFileChannel
|
|||
*
|
||||
* @param size
|
||||
* The size of the locked region; must be non-negative, and the sum
|
||||
* {@code position} + {@code size} must be non-negative
|
||||
* {@code position} + {@code size} must be non-negative.
|
||||
* A value of zero means to lock all bytes from the specified
|
||||
* starting position to the end of the file, regardless of whether
|
||||
* the file is subsequently extended or truncated
|
||||
*
|
||||
* @param shared
|
||||
* {@code true} to request a shared lock,
|
||||
|
|
|
@ -996,7 +996,9 @@ public abstract class FileChannel
|
|||
* required then a region starting at zero, and no smaller than the
|
||||
* expected maximum size of the file, should be locked. The zero-argument
|
||||
* {@link #lock()} method simply locks a region of size {@link
|
||||
* Long#MAX_VALUE}.
|
||||
* Long#MAX_VALUE}. If the {@code position} is non-negative and the
|
||||
* {@code size} is zero, then a lock of size
|
||||
* {@code Long.MAX_VALUE - position} is returned.
|
||||
*
|
||||
* <p> Some operating systems do not support shared locks, in which case a
|
||||
* request for a shared lock is automatically converted into a request for
|
||||
|
@ -1014,7 +1016,10 @@ public abstract class FileChannel
|
|||
*
|
||||
* @param size
|
||||
* The size of the locked region; must be non-negative, and the sum
|
||||
* {@code position} + {@code size} must be non-negative
|
||||
* {@code position} + {@code size} must be non-negative.
|
||||
* A value of zero means to lock all bytes from the specified
|
||||
* starting position to the end of the file, regardless of whether
|
||||
* the file is subsequently extended or truncated
|
||||
*
|
||||
* @param shared
|
||||
* {@code true} to request a shared lock, in which case this
|
||||
|
@ -1123,7 +1128,9 @@ public abstract class FileChannel
|
|||
* required then a region starting at zero, and no smaller than the
|
||||
* expected maximum size of the file, should be locked. The zero-argument
|
||||
* {@link #tryLock()} method simply locks a region of size {@link
|
||||
* Long#MAX_VALUE}.
|
||||
* Long#MAX_VALUE}. If the {@code position} is non-negative and the
|
||||
* {@code size} is zero, then a lock of size
|
||||
* {@code Long.MAX_VALUE - position} is returned.
|
||||
*
|
||||
* <p> Some operating systems do not support shared locks, in which case a
|
||||
* request for a shared lock is automatically converted into a request for
|
||||
|
@ -1141,7 +1148,10 @@ public abstract class FileChannel
|
|||
*
|
||||
* @param size
|
||||
* The size of the locked region; must be non-negative, and the sum
|
||||
* {@code position} + {@code size} must be non-negative
|
||||
* {@code position} + {@code size} must be non-negative.
|
||||
* A value of zero means to lock all bytes from the specified
|
||||
* starting position to the end of the file, regardless of whether
|
||||
* the file is subsequently extended or truncated
|
||||
*
|
||||
* @param shared
|
||||
* {@code true} to request a shared lock,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2022, 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
|
||||
|
@ -269,14 +269,36 @@ public abstract class FileLock implements AutoCloseable {
|
|||
* @param size
|
||||
* The size of the lock range
|
||||
*
|
||||
* @return {@code true} if, and only if, this lock and the given lock
|
||||
* range overlap by at least one byte
|
||||
* @return {@code true} if this lock and the given lock range overlap
|
||||
* by at least one byte; {@code false} if {@code size} is
|
||||
* negative or the lock range does not overlap this lock
|
||||
*/
|
||||
public final boolean overlaps(long position, long size) {
|
||||
if (position + size <= this.position)
|
||||
return false; // That is below this
|
||||
if (this.position + this.size <= position)
|
||||
return false; // This is below that
|
||||
if (size < 0)
|
||||
return false;
|
||||
|
||||
// Test whether this is below that
|
||||
try {
|
||||
if (Math.addExact(this.position, this.size) <= position)
|
||||
return false;
|
||||
} catch (ArithmeticException ignored) {
|
||||
// the sum of this.position and this.size overflows the range of
|
||||
// long hence their mathematical sum is greater than position
|
||||
}
|
||||
|
||||
// if size == 0 then the specified lock range is unbounded and
|
||||
// cannot be below the range of this lock
|
||||
if (size > 0) {
|
||||
// Test whether that is below this
|
||||
try {
|
||||
if (Math.addExact(position, size) <= this.position)
|
||||
return false;
|
||||
} catch (ArithmeticException ignored) {
|
||||
// the sum of position and size overflows the range of long
|
||||
// hence their mathematical sum is greater than this.position
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue