DrKLO/Telegram · error

%s: can't read from stdin

Error message

%s: can't read from stdin

What it means

Same read-error condition as error 147, but fired when the input is stdin (file_index >= argc) rather than a named file. During the memsrc read-loop, JFREAD returns fewer than INPUT_BUF_SIZE bytes with ferror(fp) true on stdin. The message says 'can't read from stdin' instead of naming a file.

Source

Thrown at TMessagesProj/jni/mozjpeg/jpegtran.c:557

      jpeg_c_get_int_param(&dstinfo, JINT_COMPRESS_PROFILE)
        == JCP_MAX_COMPRESSION)
    memsrc = TRUE; /* needed to revert to original */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
  if (memsrc) {
    size_t nbytes;
    do {
      inbuffer = (unsigned char *)realloc(inbuffer, insize + INPUT_BUF_SIZE);
      if (inbuffer == NULL) {
        fprintf(stderr, "%s: memory allocation failure\n", progname);
        exit(EXIT_FAILURE);
      }
      nbytes = JFREAD(fp, &inbuffer[insize], INPUT_BUF_SIZE);
      if (nbytes < INPUT_BUF_SIZE && ferror(fp)) {
        if (file_index < argc)
          fprintf(stderr, "%s: can't read from %s\n", progname,
                  argv[file_index]);
        else
          fprintf(stderr, "%s: can't read from stdin\n", progname);
      }
      insize += (unsigned long)nbytes;
    } while (nbytes == INPUT_BUF_SIZE);
    jpeg_mem_src(&srcinfo, inbuffer, insize);
  } else
#endif
  jpeg_stdio_src(&srcinfo, fp);

  /* Enable saving of extra markers that we want to copy */
  jcopy_markers_setup(&srcinfo, copyoption);

  /* Read file header */
  (void)jpeg_read_header(&srcinfo, TRUE);

  /* Any space needed by a transform option must be requested before
   * jpeg_read_coefficients so that memory allocation will be done right.
   */
#if TRANSFORMS_SUPPORTED

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Write the input to a temp file first, then pass the file path instead of piping through stdin
  2. Verify the piped input is complete before feeding it to jpegtran
  3. Check the exit code of the upstream command in the pipe

Example fix

// before
curl http://example.com/img.jpg | jpegtran -outfile out.jpg

// after
curl -o /tmp/input.jpg http://example.com/img.jpg
if [ $? -eq 0 ]; then
  jpegtran /tmp/input.jpg -outfile out.jpg
fi
Defensive patterns

Strategy: validation

Validate before calling

// Don't pipe; stage the input to a file first, then pass the path
int stage_stdin_to_file(const char *internal_dir, char *dst, size_t dst_len) {
    snprintf(dst, dst_len, "%s/jpegtran_stdin_%d.jpg", internal_dir, getpid());
    FILE *out = fopen(dst, "wb");
    if (!out) return -1;
    char buf[8192]; size_t n;
    while ((n = fread(buf, 1, sizeof(buf), stdin)) > 0)
        if (fwrite(buf, 1, n, out) != n) { fclose(out); return -1; }
    int err = ferror(stdin);
    fclose(out);
    return err ? -1 : 0;
}

Prevention

When it happens

Trigger: Piping input through stdin (`cat file.jpg | jpegtran`) where the pipe breaks (upstream process crashes). Reading from a terminal that sends unexpected EOF. A redirected stdin from a file on failing storage.

Common situations: A piped command where the upstream `cat` or `curl` fails mid-stream. A broken pipe from a network download piped to jpegtran. Process substitution that fails.

Related errors


AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14). Data as JSON: /api/errors/d3127662499018c7. Report an issue: GitHub.