* Parameter validator for generic yes/no function to prevent * the core from sending too long a prompt string to the * window port causing a buffer overflow there. */
| 5468 | * window port causing a buffer overflow there. |
| 5469 | */ |
| 5470 | char |
| 5471 | yn_function( |
| 5472 | const char *query, |
| 5473 | const char *resp, |
| 5474 | char def, |
| 5475 | boolean addcmdq) |
| 5476 | { |
| 5477 | char res = '\033', qbuf[QBUFSZ]; |
| 5478 | struct _cmd_queue cq, *cmdq; |
| 5479 | #ifdef DUMPLOG_CORE |
| 5480 | unsigned idx = gs.saved_pline_index; |
| 5481 | /* buffer to hold query+space+formatted_single_char_response */ |
| 5482 | char dumplog_buf[QBUFSZ + 1 + 15]; /* [QBUFSZ+1+7] should suffice */ |
| 5483 | #endif |
| 5484 | |
| 5485 | iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */ |
| 5486 | |
| 5487 | /* maximum acceptable length is QBUFSZ-1 */ |
| 5488 | if (strlen(query) >= QBUFSZ) { |
| 5489 | /* caller shouldn't have passed anything this long */ |
| 5490 | paniclog("Query truncated: ", query); |
| 5491 | (void) strncpy(qbuf, query, QBUFSZ - 1 - 3); |
| 5492 | Strcpy(&qbuf[QBUFSZ - 1 - 3], "..."); |
| 5493 | query = qbuf; |
| 5494 | } |
| 5495 | |
| 5496 | if (addcmdq && (cmdq = cmdq_pop()) != 0) { |
| 5497 | cq = *cmdq; |
| 5498 | free(cmdq); |
| 5499 | } else { |
| 5500 | cq.typ = CMDQ_USER_INPUT; |
| 5501 | cq.key = '\0'; /* lint suppression */ |
| 5502 | } |
| 5503 | |
| 5504 | if (cq.typ != CMDQ_USER_INPUT) { |
| 5505 | if (cq.typ == CMDQ_KEY) |
| 5506 | res = cq.key; |
| 5507 | else |
| 5508 | cmdq_clear(CQ_CANNED); /* 'res' is ESC */ |
| 5509 | addcmdq = FALSE; |
| 5510 | |
| 5511 | /* for the fuzzer, usually force a valid response, but sometimes let |
| 5512 | it exercise windowport yn_function and invalid response handling */ |
| 5513 | } else if (iflags.debug_fuzzer && resp && *resp && rn2(20)) { |
| 5514 | int ln = (int) strlen(resp), ridx = rn2(ln); |
| 5515 | |
| 5516 | res = resp[ridx]; |
| 5517 | /* if valid-responses includes ESC followed by unshown candidates |
| 5518 | and we randomly picked the ESC, try again with only whatever is |
| 5519 | before it; be careful to avoid rn2(0) */ |
| 5520 | if (res == '\033') { |
| 5521 | if (ln > 1) { |
| 5522 | /* if ESC is at start (ridx==0), pick something after it */ |
| 5523 | ridx = (ridx == 0) ? (1 + rn2(ln - 1)) : rn2(ridx); |
| 5524 | res = resp[ridx]; |
| 5525 | } else { |
| 5526 | /* ESC is the only thing (ln==1); something is strange... */ |
| 5527 | res = def; /* might be '\0' */ |
no test coverage detected