Explorar el Código

SshData.cs - Added 4 exception documentation, added 3 parameter checks, fixed typo in exception message for ReadString/ReadBinaryString. Also note that any call to SshData.Write(IEnumerable<byte>) will throw if passed null, List<byte>.AddRange does that for us.
SubsystemSession.cs - Added 1 exception documentation and parameter check on Constructor(Session,string,TimeSpan).
SftpClient.cs - Added more exception documentation than I care to count.
PipeStream.cs - Fixed mismatch between documentation and the actual exception in Write(byte[], int, int). Also in property Position, throwing NotImplemented but documented NotSupported. Also happens elsewhere o.O - I'm not touching this code anymore, see Workitem 819.
SemaphoreLight.cs - Added 1 exception documentation.

Kenneth_aa_cp hace 14 años
padre
commit
d8ee7d17d2

+ 6 - 6
Renci.SshClient/Renci.SshNet/Common/PipeStream.cs

@@ -127,7 +127,7 @@
         ///<exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception><filterpriority>1</filterpriority>
         public override long Seek(long offset, SeekOrigin origin)
         {
-            throw new NotImplementedException();
+            throw new NotSupportedException();
         }
 
         ///<summary>
@@ -139,7 +139,7 @@
         ///<exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception><filterpriority>2</filterpriority>
         public override void SetLength(long value)
         {
-            throw new NotImplementedException();
+            throw new NotSupportedException();
         }
 
         ///<summary>
@@ -160,9 +160,9 @@
         public override int Read(byte[] buffer, int offset, int count)
         {
             if (offset != 0)
-                throw new NotImplementedException("Offsets with value of non-zero are not supported");
+                throw new NotSupportedException("Offsets with value of non-zero are not supported");
             if (buffer == null)
-                throw new ArgumentException("Buffer is null");
+                throw new ArgumentNullException("Buffer is null");
             if (offset + count > buffer.Length)
                 throw new ArgumentException("The sum of offset and count is greater than the buffer length. ");
             if (offset < 0 || count < 0)
@@ -217,7 +217,7 @@
         public override void Write(byte[] buffer, int offset, int count)
         {
             if (buffer == null)
-                throw new ArgumentException("Buffer is null");
+                throw new ArgumentNullException("Buffer is null");
             if (offset + count > buffer.Length)
                 throw new ArgumentException("The sum of offset and count is greater than the buffer length. ");
             if (offset < 0 || count < 0)
@@ -305,7 +305,7 @@
         public override long Position
         {
             get { return 0; }
-            set { throw new NotImplementedException(); }
+            set { throw new NotSupportedException(); }
         }
 
         #endregion

+ 1 - 0
Renci.SshClient/Renci.SshNet/Common/SemaphoreLight.cs

@@ -20,6 +20,7 @@ namespace Renci.SshNet.Common
         /// the initial number of requests that can be granted concurrently.
         /// </summary>
         /// <param name="initialCount">The initial number of requests for the semaphore that can be granted concurrently.</param>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="initialCount"/> is a negative number.</exception>
         public SemaphoreLight(int initialCount)
         {
             if (initialCount < 0 )

+ 22 - 4
Renci.SshClient/Renci.SshNet/Common/SshData.cs

@@ -73,8 +73,12 @@ namespace Renci.SshNet.Common
         /// Loads data from specified bytes.
         /// </summary>
         /// <param name="value">Bytes array.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
         public void Load(byte[] value)
         {
+            if (value == null)
+                throw new ArgumentNullException("value");
+
             this.LoadBytes(value);
             this.LoadData();
         }
@@ -93,8 +97,14 @@ namespace Renci.SshNet.Common
         /// Loads data bytes into internal buffer.
         /// </summary>
         /// <param name="bytes">The bytes.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is null.</exception>
         protected void LoadBytes(byte[] bytes)
         {
+            // Note about why I check for null here, and in Load(byte[]) in this class.
+            // This method is called by several other classes, such as SshNet.Messages.Message, SshNet.Sftp.SftpMessage.
+            if (bytes == null)
+                throw new ArgumentNullException("bytes");
+
             this.ResetReader();
             this._loadedData = bytes;
             this._data = new List<byte>(bytes);
@@ -111,7 +121,7 @@ namespace Renci.SshNet.Common
         /// <summary>
         /// Reads all data left in internal buffer at current position.
         /// </summary>
-        /// <returns></returns>
+        /// <returns>An array of bytes containing the remaining data in the internal buffer.</returns>
         protected byte[] ReadBytes()
         {
             var data = new byte[this._data.Count - this._readerIndex];
@@ -123,9 +133,16 @@ namespace Renci.SshNet.Common
         /// Reads next specified number of bytes data type from internal buffer.
         /// </summary>
         /// <param name="length">Number of bytes to read.</param>
-        /// <returns></returns>
+        /// <returns>An array of bytes that was read from the internal buffer.</returns>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is greater than the internal buffer size.</exception>
         protected byte[] ReadBytes(int length)
         {
+            // Note that this also prevents allocating non-relevant lengths, such as if length is greater than _data.Count but less than int.MaxValue.
+            // For the nerds, the condition translates to: if (length > data.Count && length < int.MaxValue)
+            // Which probably would cause all sorts of exception, most notably OutOfMemoryException.
+            if (length > this._data.Count)
+                throw new ArgumentOutOfRangeException("length");
+
             var result = new byte[length];
             this._data.CopyTo(this._readerIndex, result, 0, length);
             this._readerIndex += length;
@@ -200,7 +217,7 @@ namespace Renci.SshNet.Common
 
             if (length > int.MaxValue)
             {
-                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "String that longer that {0} are not supported.", int.MaxValue));
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Strings longer than {0} is not supported.", int.MaxValue));
             }
 
             return Renci.SshNet.Common.ASCIIEncoding.Current.GetString(this.ReadBytes(length));
@@ -216,7 +233,7 @@ namespace Renci.SshNet.Common
 
             if (length > int.MaxValue)
             {
-                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "String that longer that {0} are not supported.", int.MaxValue));
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Strings longer than {0} is not supported.", int.MaxValue));
             }
 
             return this.ReadBytes(length);
@@ -265,6 +282,7 @@ namespace Renci.SshNet.Common
         /// Writes bytes array data into internal buffer.
         /// </summary>
         /// <param name="data">Byte array data to write.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
         protected void Write(IEnumerable<byte> data)
         {
             this._data.AddRange(data);

+ 31 - 0
Renci.SshClient/Renci.SshNet/SftpClient.cs

@@ -656,6 +656,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The path and name of the file to create.</param>
         /// <returns>A <see cref="SftpFileStream"/> that provides read/write access to the file specified in path</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public SftpFileStream Create(string path)
         {
             return new SftpFileStream(this._sftpSession, path, FileMode.Create, FileAccess.ReadWrite);
@@ -667,6 +668,7 @@ namespace Renci.SshNet
         /// <param name="path">The path and name of the file to create.</param>
         /// <param name="bufferSize">The number of bytes buffered for reads and writes to the file.</param>
         /// <returns>A <see cref="SftpFileStream"/> that provides read/write access to the file specified in path</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public SftpFileStream Create(string path, int bufferSize)
         {
             return new SftpFileStream(this._sftpSession, path, FileMode.Create, FileAccess.ReadWrite, bufferSize);
@@ -677,6 +679,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to be opened for writing.</param>
         /// <returns>A <see cref="System.IO.StreamWriter"/> that writes to the specified file using UTF-8 encoding.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public StreamWriter CreateText(string path)
         {
             return new StreamWriter(this.OpenWrite(path), Encoding.UTF8);
@@ -688,6 +691,7 @@ namespace Renci.SshNet
         /// <param name="path">The file to be opened for writing.</param>
         /// <param name="encoding">The character encoding to use.</param>
         /// <returns> A <see cref="System.IO.StreamWriter"/> that writes to the specified file using UTF-8 encoding. </returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public StreamWriter CreateText(string path, Encoding encoding)
         {
             return new StreamWriter(this.OpenWrite(path), encoding);
@@ -697,6 +701,7 @@ namespace Renci.SshNet
         /// Deletes the specified file or directory. An exception is not thrown if the specified file does not exist.
         /// </summary>
         /// <param name="path">The name of the file or directory to be deleted. Wildcard characters are not supported.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public void Delete(string path)
         {
             var file = this.Get(path);
@@ -709,6 +714,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file or directory for which to obtain access date and time information.</param>
         /// <returns>A <see cref="System.DateTime"/> structure set to the date and time that the specified file or directory was last accessed. This value is expressed in local time.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public DateTime GetLastAccessTime(string path)
         {
             var file = this.Get(path);
@@ -721,6 +727,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file or directory for which to obtain access date and time information.</param>
         /// <returns>A <see cref="System.DateTime"/> structure set to the date and time that the specified file or directory was last accessed. This value is expressed in UTC time.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public DateTime GetLastAccessTimeUtc(string path)
         {
             var file = this.Get(path);
@@ -733,6 +740,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file or directory for which to obtain write date and time information.</param>
         /// <returns>A <see cref="System.DateTime"/> structure set to the date and time that the specified file or directory was last written to. This value is expressed in local time.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public DateTime GetLastWriteTime(string path)
         {
             var file = this.Get(path);
@@ -745,6 +753,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file or directory for which to obtain write date and time information.</param>
         /// <returns>A <see cref="System.DateTime"/> structure set to the date and time that the specified file or directory was last written to. This value is expressed in UTC time.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public DateTime GetLastWriteTimeUtc(string path)
         {
             var file = this.Get(path);
@@ -758,6 +767,7 @@ namespace Renci.SshNet
         /// <param name="path">The file to open.</param>
         /// <param name="mode">A <see cref="System.IO.FileMode"/> value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten.</param>
         /// <returns>An unshared <see cref="SftpFileStream"/> that provides access to the specified file, with the specified mode and access.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public SftpFileStream Open(string path, FileMode mode)
         {
             return new SftpFileStream(this._sftpSession, path, mode, FileAccess.ReadWrite);
@@ -770,6 +780,7 @@ namespace Renci.SshNet
         /// <param name="mode">A <see cref="System.IO.FileMode"/> value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten.</param>
         /// <param name="access">A <see cref="System.IO.FileAccess"/> value that specifies the operations that can be performed on the file.</param>
         /// <returns>An unshared <see cref="SftpFileStream"/> that provides access to the specified file, with the specified mode and access.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public SftpFileStream Open(string path, FileMode mode, FileAccess access)
         {
             return new SftpFileStream(this._sftpSession, path, mode, access);
@@ -780,6 +791,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to be opened for reading.</param>
         /// <returns>A read-only System.IO.FileStream on the specified path.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public SftpFileStream OpenRead(string path)
         {
             return new SftpFileStream(this._sftpSession, path, FileMode.Open, FileAccess.Read);
@@ -790,6 +802,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to be opened for reading.</param>
         /// <returns>A <see cref="System.IO.StreamReader"/> on the specified path.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public StreamReader OpenText(string path)
         {
             return new StreamReader(this.OpenRead(path), Encoding.UTF8);
@@ -800,6 +813,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to be opened for writing.</param>
         /// <returns>An unshared <see cref="SftpFileStream"/> object on the specified path with <see cref="System.IO.FileAccess.Write"/> access.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public SftpFileStream OpenWrite(string path)
         {
             return new SftpFileStream(this._sftpSession, path, FileMode.OpenOrCreate, FileAccess.Write);
@@ -810,6 +824,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to open for reading.</param>
         /// <returns>A byte array containing the contents of the file.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public byte[] ReadAllBytes(string path)
         {
             using (var stream = this.OpenRead(path))
@@ -825,6 +840,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to open for reading.</param>
         /// <returns>A string array containing all lines of the file.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public string[] ReadAllLines(string path)
         {
             return this.ReadAllLines(path, Encoding.UTF8);
@@ -836,6 +852,7 @@ namespace Renci.SshNet
         /// <param name="path">The file to open for reading.</param>
         /// <param name="encoding">The encoding applied to the contents of the file.</param>
         /// <returns>A string array containing all lines of the file.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public string[] ReadAllLines(string path, Encoding encoding)
         {
             var lines = new List<string>();
@@ -854,6 +871,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to open for reading.</param>
         /// <returns>A string containing all lines of the file.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public string ReadAllText(string path)
         {
             return this.ReadAllText(path, Encoding.UTF8);
@@ -865,6 +883,7 @@ namespace Renci.SshNet
         /// <param name="path">The file to open for reading.</param>
         /// <param name="encoding">The encoding applied to the contents of the file.</param>
         /// <returns>A string containing all lines of the file.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public string ReadAllText(string path, Encoding encoding)
         {
             var lines = new List<string>();
@@ -879,6 +898,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to read.</param>
         /// <returns>The lines of the file.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public IEnumerable<string> ReadLines(string path)
         {
             return this.ReadAllLines(path);
@@ -890,6 +910,7 @@ namespace Renci.SshNet
         /// <param name="path">The file to read.</param>
         /// <param name="encoding">The encoding that is applied to the contents of the file.</param>
         /// <returns>The lines of the file.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public IEnumerable<string> ReadLines(string path, Encoding encoding)
         {
             return this.ReadAllLines(path, encoding);
@@ -944,6 +965,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to write to.</param>
         /// <param name="bytes">The bytes to write to the file.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public void WriteAllBytes(string path, byte[] bytes)
         {
             using (var stream = this.OpenWrite(path))
@@ -957,6 +979,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to write to.</param>
         /// <param name="contents">The lines to write to the file.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public void WriteAllLines(string path, IEnumerable<string> contents)
         {
             this.WriteAllLines(path, contents, Encoding.UTF8);
@@ -967,6 +990,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to write to.</param>
         /// <param name="contents">The string array to write to the file.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public void WriteAllLines(string path, string[] contents)
         {
             this.WriteAllLines(path, contents, Encoding.UTF8);
@@ -978,6 +1002,7 @@ namespace Renci.SshNet
         /// <param name="path">The file to write to.</param>
         /// <param name="contents">The lines to write to the file.</param>
         /// <param name="encoding">The character encoding to use.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public void WriteAllLines(string path, IEnumerable<string> contents, Encoding encoding)
         {
             using (var stream = this.CreateText(path, encoding))
@@ -995,6 +1020,7 @@ namespace Renci.SshNet
         /// <param name="path">The file to write to.</param>
         /// <param name="contents">The string array to write to the file.</param>
         /// <param name="encoding">An <see cref="System.Text.Encoding"/> object that represents the character encoding applied to the string array.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public void WriteAllLines(string path, string[] contents, Encoding encoding)
         {
             using (var stream = this.CreateText(path, encoding))
@@ -1011,6 +1037,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The file to write to.</param>
         /// <param name="contents">The string to write to the file.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public void WriteAllText(string path, string contents)
         {
             using (var stream = this.CreateText(path))
@@ -1025,6 +1052,7 @@ namespace Renci.SshNet
         /// <param name="path">The file to write to.</param>
         /// <param name="contents">The string to write to the file.</param>
         /// <param name="encoding">The encoding to apply to the string.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public void WriteAllText(string path, string contents, Encoding encoding)
         {
             using (var stream = this.CreateText(path, encoding))
@@ -1038,6 +1066,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The path to the file.</param>
         /// <returns>The <see cref="SftpFileAttributes"/> of the file on the path.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public SftpFileAttributes GetAttributes(string path)
         {
             var fullPath = this._sftpSession.GetCanonicalPath(path);
@@ -1050,6 +1079,7 @@ namespace Renci.SshNet
         /// </summary>
         /// <param name="path">The path to the file.</param>
         /// <param name="fileAttributes">The desired <see cref="SftpFileAttributes"/>.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         public void SetAttributes(string path, SftpFileAttributes fileAttributes)
         {
             var fullPath = this._sftpSession.GetCanonicalPath(path);
@@ -1057,6 +1087,7 @@ namespace Renci.SshNet
             this._sftpSession.RequestSetStat(fullPath, fileAttributes);
         }
 
+        // Please don't forget this when you implement these methods: <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
         //public FileSecurity GetAccessControl(string path);
         //public FileSecurity GetAccessControl(string path, AccessControlSections includeSections);
         //public DateTime GetCreationTime(string path);

+ 11 - 1
Renci.SshClient/Renci.SshNet/SubsystemSession.cs

@@ -51,9 +51,19 @@ namespace Renci.SshNet.Sftp
         //internal event EventHandler<MessageEventArgs<AttributesMessage>> AttributesMessageReceived;
 
         #endregion
-
+        
+        /// <summary>
+        /// Initializes a new instance of the SubsystemSession class.
+        /// </summary>
+        /// <exception cref="ArgumentNullException"><paramref name="session"/> or <paramref name="subsystemName"/> is null.</exception>
         public SubsystemSession(Session session, string subsystemName, TimeSpan operationTimeout)
         {
+            if (session == null)
+                throw new ArgumentNullException("session");
+
+            if (subsystemName == null)
+                throw new ArgumentNullException("subsystemName");
+                
             this._session = session;
             this._subsystemName = subsystemName;
             this._operationTimeout = operationTimeout;