1111
1212import json
1313import re
14+ import secrets
1415
1516from flask import render_template , request , current_app , Response
1617from flask_babel import gettext as _
@@ -350,6 +351,7 @@ def get_sql_util_args(data, manager, server, filepath):
350351 :param filepath: File.
351352 :return: args list.
352353 """
354+ restrict_key = secrets .token_hex (32 )
353355 args = [
354356 '--host' ,
355357 manager .local_bind_host if manager .use_ssh_tunnel else server .host ,
@@ -358,6 +360,7 @@ def get_sql_util_args(data, manager, server, filepath):
358360 else str (server .port ),
359361 '--username' , server .username , '--dbname' ,
360362 data ['database' ],
363+ '-c' , f'\\ restrict { restrict_key } ' ,
361364 '--file' , fs_short_path (filepath )
362365 ]
363366
@@ -375,43 +378,7 @@ def use_restore_utility(data, manager, server, driver, conn, filepath):
375378 return None , utility , args
376379
377380
378- def has_meta_commands (path , chunk_size = 8 * 1024 * 1024 ):
379- """
380- Quickly detect lines starting with '\' in large SQL files.
381- Works even when lines cross chunk boundaries.
382- """
383- # Look for start-of-line pattern: beginning or after newline,
384- # optional spaces, then backslash
385- pattern = re .compile (br'(^|\n)[ \t]*\\' )
386-
387- try :
388- with open (path , "rb" ) as f :
389- prev_tail = b""
390- while chunk := f .read (chunk_size ):
391- data = prev_tail + chunk
392-
393- # Search for pattern
394- if pattern .search (data ):
395- return True
396-
397- # Keep a small tail to preserve line boundary context
398- prev_tail = data [- 10 :] # keep last few bytes
399- except FileNotFoundError :
400- current_app .logger .error ("File not found." )
401- except PermissionError :
402- current_app .logger .error ("Insufficient permissions to access." )
403-
404- return False
405-
406-
407381def use_sql_utility (data , manager , server , filepath ):
408- # Check the meta commands in file.
409- if has_meta_commands (filepath ):
410- return _ ("Restore blocked: the selected PLAIN SQL file contains psql "
411- "meta-commands (for example \\ ! or \\ i). For safety, "
412- "pgAdmin does not execute meta-commands from PLAIN restores. "
413- "Please remove meta-commands." ), None , None
414-
415382 utility = manager .utility ('sql' )
416383 ret_val = does_utility_exist (utility )
417384 if ret_val :
0 commit comments