Skip to content

Commit 8ba7378

Browse files
authored
db.put(): throw INVALID_REV for invalid revs (#8931)
1 parent d62526d commit 8ba7378

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

packages/node_modules/pouchdb-core/src/adapter.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ function attachmentNameError(name) {
190190
return false;
191191
}
192192

193+
function isValidRev(rev) {
194+
return typeof rev === 'string' && /^\d+-/.test(rev);
195+
}
196+
193197
class AbstractPouchDB extends EventEmitter {
194198
_setup() {
195199
this.post = adapterFun('post', function (doc, opts, callback) {
@@ -212,6 +216,9 @@ class AbstractPouchDB extends EventEmitter {
212216
return cb(createError(NOT_AN_OBJECT));
213217
}
214218
invalidIdError(doc._id);
219+
if ('_rev' in doc && !isValidRev(doc._rev)) {
220+
return cb(createError(INVALID_REV));
221+
}
215222
if (isLocalId(doc._id) && typeof this._putLocal === 'function') {
216223
if (doc._deleted) {
217224
return this._removeLocal(doc, cb);
@@ -555,7 +562,7 @@ class AbstractPouchDB extends EventEmitter {
555562
for (var i = 0; i < leaves.length; i++) {
556563
var l = leaves[i];
557564
// looks like it's the only thing couchdb checks
558-
if (!(typeof (l) === "string" && /^\d+-/.test(l))) {
565+
if (!isValidRev(l)) {
559566
return cb(createError(INVALID_REV));
560567
}
561568
}

tests/integration/test.basics.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,54 @@ adapters.forEach(function (adapter) {
268268
});
269269
});
270270

271+
[
272+
() => '-format',
273+
() => 'bad-format',
274+
() => ({}),
275+
() => ({ toString:'2-abc' }),
276+
() => ({ toString:'2-abc', indexOf:777 }),
277+
() => ({ toString:'2-abc', indexOf:() => -1000 }),
278+
() => ({ toString:'2-abc', indexOf:() => -1000, substring:'hi' }),
279+
() => ({ toString:'2-abc', indexOf:() => -1000, substring:() => 'hi' }),
280+
() => ({ toString:() => '2-abc' }),
281+
() => ({ toString:() => '2-abc', indexOf:777 }),
282+
() => ({ toString:() => '2-abc', indexOf:() => 12 }),
283+
() => ({ toString:() => '2-abc', indexOf:() => 12, substring:'hi' }),
284+
() => ({ toString:() => '2-abc', indexOf:() => 12, substring:() => 'hi' }),
285+
({ rev }) => ({ toString:rev }),
286+
({ rev }) => ({ toString:rev, indexOf:777 }),
287+
({ rev }) => ({ toString:rev, indexOf:() => -1000 }),
288+
({ rev }) => ({ toString:rev, indexOf:() => -1000, substring:'hi' }),
289+
({ rev }) => ({ toString:rev, indexOf:() => -1000, substring:() => 'hi' }),
290+
({ rev }) => ({ toString:() => rev }),
291+
({ rev }) => ({ toString:() => rev, indexOf:777 }),
292+
({ rev }) => ({ toString:() => rev, indexOf:() => 12 }),
293+
({ rev }) => ({ toString:() => rev, indexOf:() => 12, substring:'hi' }),
294+
({ rev }) => ({ toString:() => rev, indexOf:() => 12, substring:() => 'hi' }),
295+
].forEach((generateRev, idx) => {
296+
it(`Modify a doc with illegal rev value #${idx}`, async () => {
297+
const db = new PouchDB(dbs.name);
298+
299+
const info = await db.post({ test: 'somestuff' });
300+
301+
let threw;
302+
try {
303+
await db.put({
304+
_id: info.id,
305+
_rev: generateRev(info),
306+
another: 'test'
307+
});
308+
} catch (err) {
309+
threw = true;
310+
err.message.should.equal('Invalid rev format'); // TODO should be err.reason?
311+
}
312+
313+
if (!threw) {
314+
throw new Error('db.put() should have thrown.');
315+
}
316+
});
317+
});
318+
271319
it('Remove doc', function (done) {
272320
var db = new PouchDB(dbs.name);
273321
db.post({ test: 'somestuff' }, function (err, info) {

0 commit comments

Comments
 (0)