ReviewOS

stacks/bun-query-builder

updateMany() emits no WHERE for a fragment or an empty object, rewriting every row

#1112
Closed glennmichael123 opened this 22 days ago · 0 comments
22 days ago

Found on main @ a258137, verified by execution against live Postgres 17.

updateMany(table, conditions, data) appends a WHERE only when conditions is an array, or an object that both lacks a raw key and has at least one key (client.ts ~:7882-7900). Anything else produces an UPDATE with no predicate.

Repro

// table has 4 rows
await db.updateMany('t', raw('id = 1'), { name: 'T' })   // -> 1:T 2:T 3:T 4:T
await db.updateMany('t', {},            { name: 'T' })   // -> 1:T 2:T 3:T 4:T

Both rewrite the whole table, silently, with no error.

The fragment form is the dangerous one: raw is a public export and a fragment is the natural way to express a condition updateMany cannot otherwise take, so this reads like the intended usage.

The empty-object form matters because conditions is frequently built up from user input — updateMany(t, buildFilter(req.query), data) rewrites every row the moment the filter comes back empty.

Suggested fix

Same shape as #1101: render a fragment as a predicate (it is a supported input elsewhere), and refuse a condition set that produces no WHERE rather than proceeding without one. Callers wanting an unfiltered update can say so by not passing conditions.

Found by an automated sweep; reproduced by me before filing.

Sign in to comment on this issue.