DrKLO/Telegram · error

%s: can't allocate memory for ICC profile

Error message

%s: can't allocate memory for ICC profile

What it means

jpegtran allocates a buffer for the ICC profile via malloc(icc_len) at jpegtran.c:516. If malloc returns NULL, the system cannot satisfy the allocation. The ICC profile size (determined by ftell) must be extremely large, or the process is under memory pressure. The program closes the ICC file handle and exits.

Source

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

  } else {
    /* default input file is stdin */
    fp = read_stdin();
  }

  if (icc_filename != NULL) {
    if ((icc_file = fopen(icc_filename, READ_BINARY)) == NULL) {
      fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
      exit(EXIT_FAILURE);
    }
    if (fseek(icc_file, 0, SEEK_END) < 0 ||
        (icc_len = ftell(icc_file)) < 1 ||
        fseek(icc_file, 0, SEEK_SET) < 0) {
      fprintf(stderr, "%s: can't determine size of %s\n", progname,
              icc_filename);
      exit(EXIT_FAILURE);
    }
    if ((icc_profile = (JOCTET *)malloc(icc_len)) == NULL) {
      fprintf(stderr, "%s: can't allocate memory for ICC profile\n", progname);
      fclose(icc_file);
      exit(EXIT_FAILURE);
    }
    if (fread(icc_profile, icc_len, 1, icc_file) < 1) {
      fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
              icc_filename);
      free(icc_profile);
      fclose(icc_file);
      exit(EXIT_FAILURE);
    }
    fclose(icc_file);
    if (copyoption == JCOPYOPT_ALL)
      copyoption = JCOPYOPT_ALL_EXCEPT_ICC;
  }

#ifdef PROGRESS_REPORT
  start_progress_monitor((j_common_ptr)&dstinfo, &progress);
#endif

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Sanity-check the ICC profile size before passing it: a real ICC profile is typically 500 bytes to a few MB; reject anything larger
  2. Reduce concurrent memory usage in the calling process
  3. Use a smaller ICC profile or an sRGB-compatible compressed profile

Example fix

// before
// blindly pass any file as -icc

// after
struct stat st;
stat(icc_path, &st);
if (st.st_size > 5*1024*1024) {
    fprintf(stderr, "ICC profile too large: %lld bytes\n", (long long)st.st_size);
    return -1;
}
Defensive patterns

Strategy: validation

Validate before calling

// Reject abnormally large ICC files before processing
int validate_icc_size(const char *path) {
    struct stat st;
    if (stat(path, &st) != 0) return -1;
    // Real ICC profiles: 128 bytes minimum, typically under 1MB
    if (st.st_size > 5*1024*1024) {
        fprintf(stderr, "ICC file too large: %lld bytes\n", (long long)st.st_size);
        return -1;
    }
    return 0;
}

Prevention

When it happens

Trigger: ICC file is enormous (gigabytes) due to corruption or accidental use of a non-ICC file. The process has a low address-space limit (32-bit). System memory is exhausted or a malloc limit (setrlimit RLIMIT_AS) is in effect.

Common situations: Android JNI process under heavy memory load. The '-icc' flag accidentally points to a large file that is not an ICC profile. A 32-bit build where address space is limited to ~3GB.

Related errors


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