diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-04-26 16:47:00 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2020-04-26 16:47:46 +0200 |
| commit | 44ef1c9682041fc8f861e957fb304591e316dcc1 (patch) | |
| tree | 84f5862413ee795ec3af5509a67f34bd3981da0f /src | |
| parent | a4394115e8f87b4bd2ea013d5a7c7f2984503003 (diff) | |
| download | PROJ-44ef1c9682041fc8f861e957fb304591e316dcc1.tar.gz PROJ-44ef1c9682041fc8f861e957fb304591e316dcc1.zip | |
pipeline initialization: avoid deep recursion on corrupted PROJ string like https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=21889
Diffstat (limited to 'src')
| -rw-r--r-- | src/pipeline.cpp | 12 | ||||
| -rw-r--r-- | src/proj_internal.h | 1 |
2 files changed, 13 insertions, 0 deletions
diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 511a69fe..80ee0397 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -424,6 +424,16 @@ PJ *OPERATION(pipeline,0) { int i_pipeline = -1, i_first_step = -1, i_current_step; char **argv, **current_argv; + if( P->ctx->pipelineInitRecursiongCounter == 5 ) + { + // Can happen for a string like: + // proj=pipeline step "x="""," u=" proj=pipeline step ste=""[" u=" proj=pipeline step ste="[" u=" proj=pipeline step ste="[" u=" proj=pipeline step ste="[" u=" proj=pipeline step ste="[" u=" proj=pipeline step ste="[" u=" proj=pipeline step ste="[" u=" proj=pipeline step ste="[" u=" proj=pipeline p step ste="[" u=" proj=pipeline step ste="[" u=" proj=pipeline step ste="[" u=" proj=pipeline step ste="[" u=" proj=pipeline step ""x=""""""""""" + // Probably an issue with the quoting handling code + // But doesn't hurt to add an extra safety check + proj_log_error (P, "Pipeline: too deep recursion"); + return destructor (P, PJD_ERR_MALFORMED_PIPELINE); /* ERROR: nested pipelines */ + } + P->fwd4d = pipeline_forward_4d; P->inv4d = pipeline_reverse_4d; P->fwd3d = pipeline_forward_3d; @@ -513,7 +523,9 @@ PJ *OPERATION(pipeline,0) { err = proj_errno_reset (P); + P->ctx->pipelineInitRecursiongCounter ++; next_step = pj_create_argv_internal (P->ctx, current_argc, current_argv); + P->ctx->pipelineInitRecursiongCounter --; proj_log_trace (P, "Pipeline: Step %d (%s) at %p", i, current_argv[0], next_step); if (nullptr==next_step) { diff --git a/src/proj_internal.h b/src/proj_internal.h index 3bdb5774..c69c4a30 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -735,6 +735,7 @@ struct projCtx_t { projGridChunkCache gridChunkCache{}; int projStringParserCreateFromPROJStringRecursionCounter = 0; // to avoid potential infinite recursion in PROJStringParser::createFromPROJString() + int pipelineInitRecursiongCounter = 0; // to avoid potential infinite recursion in pipeline.cpp projCtx_t() = default; projCtx_t(const projCtx_t&); |
