### The 'printf' in SubstituteFile accepts a format string as an argument, but the format string originates from the argv[3] which is controlled by user. ``` static int SubstituteFile( const char *substitutions, const char *filename) { ... fp = fopen(filename, "rt"); if (fp != NULL) { while (fgets(szBuffer, cbBuffer, fp) != NULL) { list_item_t *p = NULL; for (p = substPtr; p != NULL; p = p->nextPtr) { char *m = strstr(szBuffer, p->key); if (m) { char *cp, *op, *sp; cp = szCopy; op = szBuffer; while (op != m) *cp++ = *op++; sp = p->value; while (sp && *sp) *cp++ = *sp++; op += strlen(p->key); while (*op) *cp++ = *op++; *cp = 0; memcpy(szBuffer, szCopy, sizeof(szCopy)); } } printf(szBuffer); // Vulnerability } list_free(&substPtr); } fclose(fp); return 0; } ```