diff --git a/datasette/app.py b/datasette/app.py index da40df1e..337fcdae 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -524,10 +524,11 @@ class RowTableShared(BaseView): cells.append({ 'column': 'Link', 'value': jinja2.Markup( - '{flat_pks}'.format( + '{flat_pks}'.format( database=database, table=urllib.parse.quote_plus(table), - flat_pks=path_from_row_pks(row, pks, not pks), + flat_pks=str(jinja2.escape(path_from_row_pks(row, pks, not pks, False))), + flat_pks_quoted=path_from_row_pks(row, pks, not pks) ) ), }) diff --git a/datasette/utils.py b/datasette/utils.py index 1f296a0b..7ba663f0 100644 --- a/datasette/utils.py +++ b/datasette/utils.py @@ -38,14 +38,19 @@ def urlsafe_components(token): ] -def path_from_row_pks(row, pks, use_rowid): +def path_from_row_pks(row, pks, use_rowid, quote=True): + """ Generate an optionally URL-quoted unique identifier + for a row from its primary keys.""" if use_rowid: - return urllib.parse.quote_plus(str(row['rowid'])) - bits = [] - for pk in pks: - bits.append( - urllib.parse.quote_plus(str(row[pk])) - ) + bits = [row['rowid']] + else: + bits = [row[pk] for pk in pks] + + if quote: + bits = [urllib.parse.quote_plus(str(bit)) for bit in bits] + else: + bits = [str(bit) for bit in bits] + return ','.join(bits)