Skip to content

Commit c9fdfbb

Browse files
committed
Make maximum recursion depth of run_sql configurable
fixes #739
1 parent b6f3c0b commit c9fdfbb

File tree

5 files changed

+20
-7
lines changed

5 files changed

+20
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
- Fix a bug where stacked bar charts would not stack the bars correctly in some cases.
2929
- Update ApexCharts to [v4.1.0](https://github.com/apexcharts/apexcharts.js/releases/tag/v4.1.0).
3030
- Temporarily disable automatic tick amount calculation in the chart component. This was causing issues with mislabeled x-axis data, because of a bug in ApexCharts.
31+
- Add a new `max_recursion_depth` configuration option to limit the depth of recursion allowed in the `run_sql` function.
3132

3233
## 0.31.0 (2024-11-24)
3334

configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Here are the available configuration options and their default values:
3333
| `environment` | development | The environment in which SQLPage is running. Can be either `development` or `production`. In `production` mode, SQLPage will hide error messages and stack traces from the user, and will cache sql files in memory to avoid reloading them from disk. |
3434
| `content_security_policy` | `script-src 'self' 'nonce-XXX` | The [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) to set in the HTTP headers. If you get CSP errors in the browser console, you can set this to the empty string to disable CSP. |
3535
| `system_root_ca_certificates` | false | Whether to use the system root CA certificates to validate SSL certificates when making http requests with `sqlpage.fetch`. If set to false, SQLPage will use its own set of root CA certificates. If the `SSL_CERT_FILE` or `SSL_CERT_DIR` environment variables are set, they will be used instead of the system root CA certificates. |
36+
| `max_recursion_depth` | 10 | Maximum depth of recursion allowed in the `run_sql` function. Maximum value is 255. |
3637

3738
Multiple configuration file formats are supported:
3839
you can use a [`.json5`](https://json5.org/) file, a [`.toml`](https://toml.io/) file, or a [`.yaml`](https://en.wikipedia.org/wiki/YAML#Syntax) file.

examples/official-site/sqlpage/migrations/38_run_sql.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ select ''dynamic'' as component, sqlpage.run_sql(''common_header.sql'') as prope
2626
2727
#### Notes
2828
29-
- **recursion**: you can use `run_sql` to include a file that itself includes another file, and so on. However, be careful to avoid infinite loops. SQLPage will throw an error if the inclusion depth is superior to 8.
29+
- **recursion**: you can use `run_sql` to include a file that itself includes another file, and so on. However, be careful to avoid infinite loops. SQLPage will throw an error if the inclusion depth is superior to `max_recursion_depth` (10 by default).
3030
- **security**: be careful when using `run_sql` to include files. Never use `run_sql` with a user-provided parameter. Never run a file uploaded by a user, or a file that is not under your control.
3131
- **variables**: the included file will have access to the same variables (URL parameters, POST variables, etc.)
3232
as the calling file.

src/app_config.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ pub struct AppConfig {
243243
/// `SSL_CERT_FILE` and `SSL_CERT_DIR` environment variables.
244244
#[serde(default = "default_system_root_ca_certificates")]
245245
pub system_root_ca_certificates: bool,
246+
247+
/// Maximum depth of recursion allowed in the `run_sql` function.
248+
#[serde(default = "default_max_recursion_depth")]
249+
pub max_recursion_depth: u8,
246250
}
247251

248252
impl AppConfig {
@@ -490,6 +494,10 @@ fn default_system_root_ca_certificates() -> bool {
490494
|| std::env::var("SSL_CERT_DIR").is_ok_and(|x| !x.is_empty())
491495
}
492496

497+
fn default_max_recursion_depth() -> u8 {
498+
10
499+
}
500+
493501
#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Copy, Eq, Default)]
494502
#[serde(rename_all = "lowercase")]
495503
pub enum DevOrProd {

src/webserver/database/sqlpage_functions/functions.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -448,11 +448,11 @@ async fn run_sql<'a>(
448448
log::debug!("run_sql: first argument is NULL, returning NULL");
449449
return Ok(None);
450450
};
451-
let sql_file = request
452-
.app_state
451+
let app_state = &request.app_state;
452+
let sql_file = app_state
453453
.sql_file_cache
454454
.get_with_privilege(
455-
&request.app_state,
455+
app_state,
456456
std::path::Path::new(sql_file_path.as_ref()),
457457
true,
458458
)
@@ -466,11 +466,14 @@ async fn run_sql<'a>(
466466
} else {
467467
request.clone()
468468
};
469-
if tmp_req.clone_depth > 8 {
470-
anyhow::bail!("Too many nested inclusions. run_sql can include a file that includes another file, but the depth is limited to 8 levels. \n\
469+
let max_recursion_depth = app_state.config.max_recursion_depth;
470+
if tmp_req.clone_depth > max_recursion_depth {
471+
anyhow::bail!("Too many nested inclusions. run_sql can include a file that includes another file, but the depth is limited to {max_recursion_depth} levels. \n\
471472
Executing sqlpage.run_sql('{sql_file_path}') would exceed this limit. \n\
472473
This is to prevent infinite loops and stack overflows.\n\
473-
Make sure that your SQL file does not try to run itself, directly or through a chain of other files.");
474+
Make sure that your SQL file does not try to run itself, directly or through a chain of other files.\n\
475+
If you need to include more files, you can increase max_recursion_depth in the configuration file.\
476+
");
474477
}
475478
let mut results_stream =
476479
crate::webserver::database::execute_queries::stream_query_results_boxed(

0 commit comments

Comments
 (0)