DrKLO/Telegram · error

%s: can't open %s

Error message

%s: can't open %s

What it means

wrjpgcom is a mozjpeg CLI tool that inserts/replaces JPEG comment (COM) markers. The -cfile switch tells it to read the new comment text from an external file. This message is printed to stderr and the process exits with EXIT_FAILURE when fopen(argv[argn], "r") on that comment file returns NULL, i.e. the file cannot be opened for reading. The first %s is progname (argv[0]), the second is the offending path.

Source

Thrown at TMessagesProj/jni/mozjpeg/wrjpgcom.c:437

  argc = ccommand(&argv);
#endif

  progname = argv[0];
  if (progname == NULL || progname[0] == 0)
    progname = "wrjpgcom";      /* in case C library doesn't provide it */

  /* Parse switches, if any */
  for (argn = 1; argn < argc; argn++) {
    arg = argv[argn];
    if (arg[0] != '-')
      break;                    /* not switch, must be file name */
    arg++;                      /* advance over '-' */
    if (keymatch(arg, "replace", 1)) {
      keep_COM = 0;
    } else if (keymatch(arg, "cfile", 2)) {
      if (++argn >= argc) usage();
      if ((comment_file = fopen(argv[argn], "r")) == NULL) {
        fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]);
        exit(EXIT_FAILURE);
      }
    } else if (keymatch(arg, "comment", 1)) {
      if (++argn >= argc) usage();
      comment_arg = argv[argn];
      /* If the comment text starts with '"', then we are probably running
       * under MS-DOG and must parse out the quoted string ourselves.  Sigh.
       */
      if (comment_arg[0] == '"') {
        comment_arg = (char *)malloc((size_t)MAX_COM_LENGTH);
        if (comment_arg == NULL)
          ERREXIT("Insufficient memory");
        if (strlen(argv[argn]) + 2 >= (size_t)MAX_COM_LENGTH) {
          fprintf(stderr, "Comment text may not exceed %u bytes\n",
                  (unsigned int)MAX_COM_LENGTH);
          exit(EXIT_FAILURE);
        }
        strcpy(comment_arg, argv[argn] + 1);

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Verify the -cfile path is readable before running: run `test -r <path>` or stat() it from the caller.
  2. Pass an absolute path instead of a relative one to remove cwd ambiguity.
  3. Check permissions/ownership of the target file and the directory leading to it.
  4. Confirm the path points to a regular file, not a directory or device node.

Example fix

// before
wrjpgcom -cfile notes.txt photo.jpg   # notes.txt not in cwd
// after
wrjpgcom -cfile /sdcard/comments/notes.txt photo.jpg
Defensive patterns

Strategy: validation

Validate before calling

/* C caller: verify -cfile target is readable before exec'ing wrjpgcom */
#include <unistd.h>
if (access(cfile_path, R_OK) != 0) {
    /* report missing/unreadable comment file; do not invoke */
    return -1;
}

Prevention

When it happens

Trigger: Invoking `wrjpgcom -cfile <path> [input.jpg]` where <path> does not exist, is not a regular file, or lacks read permission. The check runs during argv parsing, before any JPEG input is touched.

Common situations: Typo or wrong relative path (cwd differs from expectation), file on a read-only/unmounted volume, SELinux/Android permission denial in the TMessagesProj JNI context, or passing a directory name instead of a file.

Related errors


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