Fix crash on edit s, p, u key 'U' with negative argument
ef_ensure_space() oopses on negative ID, but succeeds anyway. edit()
proceeds to ef_write(), which neglects to check for negative ID.
Since the ID isn't in the cache, it then passes a NULL old element to
callback prewrite(), which crashes.
Fix ef_ensure_space() to fail on negative ID. Commit 5173f8cd
(v4.3.0) made it oops, but neglected to make it fail.
Fix ef_write() to oops and fail on negative ID.
ef_write() still passes NULL old element to prewrite() when the ID
isn't in the cache. Doesn't actually happen, because we use
prewrite() callbacks only with fully cached tables. Fragile. Make
ef_open() fail when that assumption is violated.
This commit is contained in:
parent
9da83c54c0
commit
bc14b41c65
1 changed files with 6 additions and 3 deletions
|
@ -29,7 +29,7 @@
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Dave Pare, 1989
|
* Dave Pare, 1989
|
||||||
* Steve McClure, 2000
|
* Steve McClure, 2000
|
||||||
* Markus Armbruster, 2005-2012
|
* Markus Armbruster, 2005-2013
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
@ -85,6 +85,8 @@ ef_open(int type, int how)
|
||||||
ep = &empfile[type];
|
ep = &empfile[type];
|
||||||
if (CANT_HAPPEN(!ep->file || ep->base != EF_BAD || ep->fd >= 0))
|
if (CANT_HAPPEN(!ep->file || ep->base != EF_BAD || ep->fd >= 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (CANT_HAPPEN(ep->prewrite && !(how & EFF_MEM)))
|
||||||
|
return 0; /* not implemented */
|
||||||
oflags = O_RDWR;
|
oflags = O_RDWR;
|
||||||
if (how & EFF_PRIVATE)
|
if (how & EFF_PRIVATE)
|
||||||
oflags = O_RDONLY;
|
oflags = O_RDONLY;
|
||||||
|
@ -542,6 +544,8 @@ ef_write(int type, int id, void *from)
|
||||||
ep = &empfile[type];
|
ep = &empfile[type];
|
||||||
if (CANT_HAPPEN((ep->flags & (EFF_MEM | EFF_PRIVATE)) == EFF_PRIVATE))
|
if (CANT_HAPPEN((ep->flags & (EFF_MEM | EFF_PRIVATE)) == EFF_PRIVATE))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (CANT_HAPPEN(id < 0))
|
||||||
|
return 0;
|
||||||
if (CANT_HAPPEN(ep->nent >= 0 && id >= ep->nent))
|
if (CANT_HAPPEN(ep->nent >= 0 && id >= ep->nent))
|
||||||
return 0; /* beyond fixed size */
|
return 0; /* beyond fixed size */
|
||||||
new_seqno(ep, from);
|
new_seqno(ep, from);
|
||||||
|
@ -966,9 +970,8 @@ ef_check(int type)
|
||||||
int
|
int
|
||||||
ef_ensure_space(int type, int id, int count)
|
ef_ensure_space(int type, int id, int count)
|
||||||
{
|
{
|
||||||
if (ef_check(type) < 0)
|
if (ef_check(type) < 0 || CANT_HAPPEN(id < 0))
|
||||||
return 0;
|
return 0;
|
||||||
CANT_HAPPEN(id < 0);
|
|
||||||
|
|
||||||
while (id >= empfile[type].fids) {
|
while (id >= empfile[type].fids) {
|
||||||
if (!ef_extend(type, count))
|
if (!ef_extend(type, count))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue