casaroli commented on code in PR #20460:
URL: https://github.com/apache/nuttx/pull/20460#discussion_r4392213399
##########
fs/procfs/fs_procfsutil.c:
##########
@@ -45,6 +51,114 @@
#define LINEBUF_SIZE 128
+#if defined(CONFIG_FS_LARGEFILE)
+# define OFF_MAX INT64_MAX
+#else
+# define OFF_MAX INT32_MAX
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Private windowed output stream state used by procfs_format_read(). */
+
+struct procfs_format_stream_s
+{
+ struct lib_outstream_s common; /* Common stream state; nput is the logical
+ * count of all bytes offered so far */
+ FAR char *buffer; /* User receive buffer */
+ size_t buflen; /* Representable copy capacity of buffer */
+ size_t copied; /* Bytes copied to buffer so far */
+ off_t skip; /* Bytes still to skip before the window */
+ int err; /* First sticky negative errno, or zero */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: procfs_format_puts
+ *
+ * Description:
+ * Consume one renderer output block through the window: bytes before the
+ * requested file position reduce the remaining skip, bytes intersecting
+ * the user buffer are copied, and bytes beyond it are discarded. A block
+ * whose length cannot be represented in the logical count records a
+ * sticky deferred -EOVERFLOW.
+ *
+ ****************************************************************************/
+
+static ssize_t procfs_format_puts(FAR struct lib_outstream_s *self,
+ FAR const void *buf, size_t len)
+{
+ FAR struct procfs_format_stream_s *stream =
+ (FAR struct procfs_format_stream_s *)self;
+ FAR const char *src = buf;
+ size_t chunk;
+
+ if (stream->err < 0 || len == 0)
+ {
+ return len;
+ }
+
+ /* Reject a block whose length cannot be represented in the logical count
+ * before it changes the count or the buffer.
+ */
+
+ if (len > OFF_MAX - stream->common.nput)
+ {
+ stream->err = -EOVERFLOW;
+ return len;
+ }
+
+ stream->common.nput += len;
+
+ /* Region 1: bytes before the requested file position */
+
+ if (stream->skip > 0)
+ {
+ if (len <= stream->skip)
+ {
+ stream->skip -= len;
+ return len;
+ }
+
+ len -= stream->skip;
+ src += stream->skip;
+ stream->skip = 0;
+ }
+
+ /* Region 2: bytes intersecting the user buffer */
+
+ chunk = MIN(len, stream->buflen - stream->copied);
+
+ if (chunk > 0)
+ {
+ memcpy(stream->buffer + stream->copied, src, chunk);
+ stream->copied += chunk;
+ }
+
+ /* Region 3: bytes beyond the buffer are discarded. The read entry point
+ * already clamped buflen so the copied count and advanced file position
+ * stay representable, so no per-byte overflow check is needed here.
+ */
+
+ return len;
Review Comment:
After a partial skip, `len` is only the rest of the block, so the function
returns fewer bytes than it consumed and a buffered stream sees a short write.
Fix: save the length at entry and return it on every path.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]