Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

socket.recv() and recvfrom() with MSG_TRUNC raise ValueError and lose the datagram since 3.15.1

Abierto
#160,622 0 comentarios 1 reacción 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
43/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
python

Línea de trabajo

Start by tracing socket.recv() and recvfrom() through sock_recv() and sock_recvfrom() to PyBytesWriter_FinishWithSize(), then inspect the change from gh-157226 and the existing behavior discussed in gh-69121. Reproduce the reported case on Linux and check how recvmsg() handles truncated datagrams. Done means defining and verifying behavior that avoids raising after consuming the datagram and avoids returning invalid padding bytes.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

extension-modules topic-socket type-bug
Bug report
Bug description:

Since 3.15.1, socket.recv(bufsize, MSG_TRUNC) and socket.recvfrom(bufsize, MSG_TRUNC) raise ValueError: size larger than allocated size when the datagram is longer than bufsize. Without MSG_PEEK, the datagram is already consumed by the time the exception is raised, so the data is lost:

import socket
a, b = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM)
a.send(b"abcdefgh")
a.send(b"second")
try:
    print(b.recv(2, socket.MSG_TRUNC))
except ValueError as e:
    print(e)
try:
    print(b.recvfrom(2, socket.MSG_TRUNC))
except ValueError as e:
    print(e)
b.setblocking(False)
b.recv(100)  # BlockingIOError: both datagrams are gone

3.15.1:

size larger than allocated size
size larger than allocated size

3.15.0 and 3.14 (the long-standing behavior, see gh-69121):

b'ab\x00\x00\x00\x00\x00\x00'
(b'se\x00\x00\x00\x00', None)

With MSG_TRUNC, Linux recv(2) returns the real length of the datagram even if it was longer than the buffer. sock_recv() and sock_recvfrom() pass that length to PyBytesWriter_FinishWithSize(), which, after c38a347e2c3199d7d3f6a9eefbf46df52caf725d (backport of gh-157226 to 3.15), rejects a size larger than the allocated one. The same code is in main.

The old behavior was a bug too (gh-69121): the returned object was grown to the real datagram length, with only the first bufsize bytes being valid. Still, it is a behavior change in a bugfix release that breaks working code. For example, CRIU's pycriu used len(s.recv(1, socket.MSG_TRUNC | socket.MSG_PEEK)) to find out the message size (fixed in checkpoint-restore/criu#3268 by using recv_into(), which returns the value from recv(2) as is).

Raising after the data is consumed seems to be the worst option. Returning the min(outlen, bufsize) bytes actually received (as suggested in gh-69121, and similar to what recvmsg() does) would avoid both the data loss and the garbage bytes.

CPython versions tested on:

3.14, 3.15

Operating systems tested on:

Linux

Linked PRs
  • gh-160677
Lenguaje dominante
Python
Estrellas
77.7k
Forks
38.3k
Merge medio
13 h 30 min
PR fusionados (30 d)
708

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de python/cpython

Todos los issues de python/cpython

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.