cozy-pouch-link 60.36.1 → 60.36.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -535,7 +535,7 @@ var makeSQLQueryFromMango = function makeSQLQueryFromMango(_ref3) {
535
535
  // queries the winning rev). `data` aliases 'by-sequence'.json; `deleted` lives
536
536
  // only on by-sequence, so the where clause stays unambiguous.
537
537
 
538
- var sql = ["SELECT 'by-sequence'.json AS data, 'by-sequence'.doc_id, 'by-sequence'.rev", "FROM 'by-sequence' INDEXED BY ".concat(indexName, ", 'document-store'"), "WHERE 'by-sequence'.seq = 'document-store'.winningseq AND ".concat(whereClause)].join(' ');
538
+ var sql = ["SELECT 'by-sequence'.json AS data, 'by-sequence'.doc_id, 'by-sequence'.rev", "FROM 'by-sequence' INDEXED BY '".concat(escapeSQLString(indexName), "', 'document-store'"), "WHERE 'by-sequence'.seq = 'document-store'.winningseq AND ".concat(whereClause)].join(' ');
539
539
 
540
540
  if (sortClause) {
541
541
  sql += " ORDER BY ".concat(sortClause);
@@ -597,7 +597,7 @@ var makeSQLQueryAll = function makeSQLQueryAll() {
597
597
  exports.makeSQLQueryAll = makeSQLQueryAll;
598
598
 
599
599
  var makeSQLDropIndex = function makeSQLDropIndex(indexName) {
600
- return "DROP INDEX IF EXISTS '".concat(indexName, "';");
600
+ return "DROP INDEX IF EXISTS '".concat(escapeSQLString(indexName), "';");
601
601
  };
602
602
 
603
603
  exports.makeSQLDropIndex = makeSQLDropIndex;
@@ -606,15 +606,16 @@ var makeSQLCreateMangoIndex = function makeSQLCreateMangoIndex(indexName, fields
606
606
  var partialFilter = _ref5.partialFilter;
607
607
  // Escaped like the where clause's paths, so an index covers exactly the
608
608
  // expression makeWhereClause emits for the same field.
609
- // XXX - indexName itself is still interpolated raw here, in makeSQLDropIndex
610
- // and in makeSQLQueryFromMango's INDEXED BY. The three must agree, so they are
611
- // left alone together: a field name containing a quote would break index
612
- // resolution rather than the where clause.
609
+ // The index name is quoted and escaped here, in makeSQLDropIndex and in
610
+ // makeSQLQueryFromMango's INDEXED BY. The three must agree: a partial filter
611
+ // puts its own values in the name, so it can hold parentheses and a dollar,
612
+ // which SQLite refuses to parse as a bare identifier, and a quote, which
613
+ // would end the quoted one.
613
614
  var jsonAttributes = fieldsToIndex.map(function (field) {
614
615
  return "json_extract(json, '$.".concat(escapeSQLString(field), "')");
615
616
  });
616
617
  var jsonIndex = jsonAttributes.join(',');
617
- var sql = "\n CREATE INDEX IF NOT EXISTS '".concat(indexName, "'\n ON 'by-sequence'\n (").concat(jsonIndex, ")\n ");
618
+ var sql = "\n CREATE INDEX IF NOT EXISTS '".concat(escapeSQLString(indexName), "'\n ON 'by-sequence'\n (").concat(jsonIndex, ")\n ");
618
619
 
619
620
  if (partialFilter) {
620
621
  // `data` only exists as a SELECT alias of 'by-sequence'.json; inside CREATE
@@ -9,6 +9,7 @@ import {
9
9
  makeSQLQueryAll,
10
10
  parseResults,
11
11
  makeSQLCreateMangoIndex,
12
+ makeSQLDropIndex,
12
13
  toWebSQLResult
13
14
  } from './sql'
14
15
 
@@ -159,7 +160,7 @@ describe('makeSQLQueryFromMango', () => {
159
160
 
160
161
  const expectedSql = [
161
162
  `SELECT 'by-sequence'.json AS data, 'by-sequence'.doc_id, 'by-sequence'.rev`,
162
- `FROM 'by-sequence' INDEXED BY by_name, 'document-store'`,
163
+ `FROM 'by-sequence' INDEXED BY 'by_name', 'document-store'`,
163
164
  `WHERE 'by-sequence'.seq = 'document-store'.winningseq AND DELETED = 0 AND (json_extract(data, '$.date') > '2025-01-01')`,
164
165
  `LIMIT 100;`
165
166
  ].join(' ')
@@ -175,7 +176,7 @@ describe('makeSQLQueryFromMango', () => {
175
176
 
176
177
  const expectedSql = [
177
178
  `SELECT 'by-sequence'.json AS data, 'by-sequence'.doc_id, 'by-sequence'.rev`,
178
- `FROM 'by-sequence' INDEXED BY by_name, 'document-store'`,
179
+ `FROM 'by-sequence' INDEXED BY 'by_name', 'document-store'`,
179
180
  `WHERE 'by-sequence'.seq = 'document-store'.winningseq AND DELETED = 0 AND (json_extract(data, '$.date') > '2025-01-01')`,
180
181
  `ORDER BY json_extract(data, '$.date') ASC`,
181
182
  `LIMIT 100;`
@@ -197,7 +198,7 @@ describe('makeSQLQueryFromMango', () => {
197
198
 
198
199
  const expectedSql = [
199
200
  `SELECT 'by-sequence'.json AS data, 'by-sequence'.doc_id, 'by-sequence'.rev`,
200
- `FROM 'by-sequence' INDEXED BY by_name, 'document-store'`,
201
+ `FROM 'by-sequence' INDEXED BY 'by_name', 'document-store'`,
201
202
  `WHERE 'by-sequence'.seq = 'document-store'.winningseq AND DELETED = 0 AND (json_extract(data, '$.date') > '2025-01-01')`,
202
203
  `LIMIT 200 OFFSET 100;`
203
204
  ].join(' ')
@@ -226,6 +227,33 @@ describe('makeSQLQueryFromMango', () => {
226
227
  expect(sql).not.toContain('LIMIT null')
227
228
  expect(sql).toContain('LIMIT -1 OFFSET 10;')
228
229
  })
230
+
231
+ it('should quote an index name a partial filter made non-alphanumeric', () => {
232
+ const selector = { date: { $gt: '2025-01-01' } }
233
+ const indexName = 'by_date_filter_(_id_$nin_(io.cozy.files.trash-dir))'
234
+ const sql = makeSQLQueryFromMango({ selector, indexName, limit: 100 })
235
+
236
+ expect(sql).toContain(`INDEXED BY '${indexName}'`)
237
+ })
238
+
239
+ it('escapes a quote a partial filter value put in the index name', () => {
240
+ const indexName = "by_name_filter_(name_$ne_O'Brien)"
241
+ const escaped = "by_name_filter_(name_$ne_O''Brien)"
242
+ const query = makeSQLQueryFromMango({
243
+ selector: { date: { $gt: '2025-01-01' } },
244
+ indexName,
245
+ limit: 100
246
+ })
247
+
248
+ // The three statements must name the same index, so they escape alike.
249
+ expect(query).toContain(`INDEXED BY '${escaped}'`)
250
+ expect(makeSQLCreateMangoIndex(indexName, ['name'], {})).toContain(
251
+ `CREATE INDEX IF NOT EXISTS '${escaped}'`
252
+ )
253
+ expect(makeSQLDropIndex(indexName)).toBe(
254
+ `DROP INDEX IF EXISTS '${escaped}';`
255
+ )
256
+ })
229
257
  })
230
258
 
231
259
  describe('makeSQLQueryAll', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-pouch-link",
3
- "version": "60.36.1",
3
+ "version": "60.36.2",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "types/index.d.ts",
@@ -41,5 +41,5 @@
41
41
  "typecheck": "tsc -p tsconfig.json"
42
42
  },
43
43
  "sideEffects": false,
44
- "gitHead": "113938e0db48b2fa03eb2afdd495757a29f2bb5a"
44
+ "gitHead": "ba55d3b65b937785254c369ef2bc86ad31cbc658"
45
45
  }