From 2d49a26790d432ae313ce3010a97ed2f266a46d6 Mon Sep 17 00:00:00 2001 From: Bert Date: Thu, 4 Apr 2024 13:48:07 -0400 Subject: [PATCH] ensure table names are uri encoded for tables (#1189) This prevents an issue where users can do something like: ```js db.createTable('my-table#123123') ``` The server has logic to determine that '#' character is not allowed in the table name, but currently this is being returned as 404 error because it routes to `/v1/my-table#123123/create` and `#123123/create` will not be parsed as part of path --- node/src/remote/index.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/node/src/remote/index.ts b/node/src/remote/index.ts index 8fc4178d..17b9443d 100644 --- a/node/src/remote/index.ts +++ b/node/src/remote/index.ts @@ -156,7 +156,7 @@ export class RemoteConnection implements Connection { } const res = await this._client.post( - `/v1/table/${tableName}/create/`, + `/v1/table/${encodeURIComponent(tableName)}/create/`, buffer, undefined, 'application/vnd.apache.arrow.stream' @@ -177,7 +177,7 @@ export class RemoteConnection implements Connection { } async dropTable (name: string): Promise { - await this._client.post(`/v1/table/${name}/drop/`) + await this._client.post(`/v1/table/${encodeURIComponent(name)}/drop/`) } withMiddleware (middleware: HttpMiddleware): Connection { @@ -268,7 +268,7 @@ export class RemoteTable implements Table { get schema (): Promise { return this._client - .post(`/v1/table/${this._name}/describe/`) + .post(`/v1/table/${encodeURIComponent(this._name)}/describe/`) .then(async (res) => { if (res.status !== 200) { throw new Error( @@ -282,7 +282,7 @@ export class RemoteTable implements Table { } search (query: T): Query { - return new RemoteQuery(query, this._client, this._name) //, this._embeddings_new) + return new RemoteQuery(query, this._client, encodeURIComponent(this._name)) //, this._embeddings_new) } filter (where: string): Query { @@ -324,7 +324,7 @@ export class RemoteTable implements Table { const buffer = await fromTableToStreamBuffer(tbl, this._embeddings) const res = await this._client.post( - `/v1/table/${this._name}/merge_insert/`, + `/v1/table/${encodeURIComponent(this._name)}/merge_insert/`, buffer, queryParams, 'application/vnd.apache.arrow.stream' @@ -348,7 +348,7 @@ export class RemoteTable implements Table { const buffer = await fromTableToStreamBuffer(tbl, this._embeddings) const res = await this._client.post( - `/v1/table/${this._name}/insert/`, + `/v1/table/${encodeURIComponent(this._name)}/insert/`, buffer, { mode: 'append' @@ -374,7 +374,7 @@ export class RemoteTable implements Table { } const buffer = await fromTableToStreamBuffer(tbl, this._embeddings) const res = await this._client.post( - `/v1/table/${this._name}/insert/`, + `/v1/table/${encodeURIComponent(this._name)}/insert/`, buffer, { mode: 'overwrite' @@ -421,7 +421,7 @@ export class RemoteTable implements Table { index_cache_size: indexCacheSize } const res = await this._client.post( - `/v1/table/${this._name}/create_index/`, + `/v1/table/${encodeURIComponent(this._name)}/create_index/`, data ) if (res.status !== 200) { @@ -442,7 +442,7 @@ export class RemoteTable implements Table { replace: true } const res = await this._client.post( - `/v1/table/${this._name}/create_scalar_index/`, + `/v1/table/${encodeURIComponent(this._name)}/create_scalar_index/`, data ) if (res.status !== 200) { @@ -455,14 +455,14 @@ export class RemoteTable implements Table { } async countRows (filter?: string): Promise { - const result = await this._client.post(`/v1/table/${this._name}/count_rows/`, { + const result = await this._client.post(`/v1/table/${encodeURIComponent(this._name)}/count_rows/`, { predicate: filter }) return (await result.body()) } async delete (filter: string): Promise { - await this._client.post(`/v1/table/${this._name}/delete/`, { + await this._client.post(`/v1/table/${encodeURIComponent(this._name)}/delete/`, { predicate: filter }) } @@ -481,7 +481,7 @@ export class RemoteTable implements Table { updates[key] = toSQL(value) } } - await this._client.post(`/v1/table/${this._name}/update/`, { + await this._client.post(`/v1/table/${encodeURIComponent(this._name)}/update/`, { predicate: filter, updates: Object.entries(updates).map(([key, value]) => [key, value]) }) @@ -489,7 +489,7 @@ export class RemoteTable implements Table { async listIndices (): Promise { const results = await this._client.post( - `/v1/table/${this._name}/index/list/` + `/v1/table/${encodeURIComponent(this._name)}/index/list/` ) return (await results.body()).indexes?.map((index: any) => ({ columns: index.columns, @@ -500,7 +500,7 @@ export class RemoteTable implements Table { async indexStats (indexUuid: string): Promise { const results = await this._client.post( - `/v1/table/${this._name}/index/${indexUuid}/stats/` + `/v1/table/${encodeURIComponent(this._name)}/index/${indexUuid}/stats/` ) const body = await results.body() return {