aboutsummaryrefslogtreecommitdiff
path: root/src/pipeline.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-08-21 16:29:24 +0200
committerEven Rouault <even.rouault@spatialys.com>2021-08-21 16:29:24 +0200
commitbe954086540afbf4faf7b5db78d0668f8d86df9b (patch)
tree047c86e9ef1f3ffb1f0f9956f617c3e92c4a103f /src/pipeline.cpp
parent6ee8c26b60e99e347dad8b7d6fb33b5316973f9d (diff)
downloadPROJ-be954086540afbf4faf7b5db78d0668f8d86df9b.tar.gz
PROJ-be954086540afbf4faf7b5db78d0668f8d86df9b.zip
pipeline instanciation: fix potential O(n^2) performance. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=37438
Diffstat (limited to 'src/pipeline.cpp')
-rw-r--r--src/pipeline.cpp67
1 files changed, 29 insertions, 38 deletions
diff --git a/src/pipeline.cpp b/src/pipeline.cpp
index 88793027..74ab2488 100644
--- a/src/pipeline.cpp
+++ b/src/pipeline.cpp
@@ -387,37 +387,6 @@ static void set_ellipsoid(PJ *P) {
}
-static enum pj_io_units get_next_non_whatever_unit(struct Pipeline* pipeline, size_t step, PJ_DIRECTION dir) {
- const auto& steps = pipeline->steps;
- const auto nsteps = steps.size();
-
- if (dir == PJ_FWD) {
- for (size_t i = step+1; i<nsteps; i++) {
- auto pj = steps[i].pj;
- if (pj_left(pj) != pj_right(pj))
- return pj_left(pj);
- if (pj_left(pj) != PJ_IO_UNITS_WHATEVER)
- return pj_left(pj);
- if (pj_right(pj) != PJ_IO_UNITS_WHATEVER)
- return pj_right(pj);
- }
- } else {
- for (size_t i=step; i>0;) {
- i--;
- auto pj = steps[i].pj;
- if (pj_right(pj) != pj_left(pj))
- return pj_right(pj);
- if (pj_right(pj) != PJ_IO_UNITS_WHATEVER)
- return pj_right(pj);
- if (pj_left(pj) != PJ_IO_UNITS_WHATEVER)
- return pj_left(pj);
- }
- }
- return PJ_IO_UNITS_WHATEVER;
-}
-
-
-
PJ *OPERATION(pipeline,0) {
int i, nsteps = 0, argc;
int i_pipeline = -1, i_first_step = -1, i_current_step;
@@ -585,20 +554,42 @@ PJ *OPERATION(pipeline,0) {
/* proj=pipeline step proj=unitconvert xy_in=deg xy_out=rad step ... */
/* where the left-hand side units of the first step shouldn't be changed to RADIANS */
/* as it will result in deg->rad conversions in cs2cs and other applications. */
- for (i=0; i<nsteps; i++) {
+
+ for (i=nsteps-2; i>=0; --i) {
auto pj = pipeline->steps[i].pj;
if (pj_left(pj) == PJ_IO_UNITS_WHATEVER && pj_right(pj) == PJ_IO_UNITS_WHATEVER) {
- pj->left = get_next_non_whatever_unit(pipeline, i, PJ_FWD);
- pj->right = get_next_non_whatever_unit(pipeline, i, PJ_FWD);
+ const auto right_pj = pipeline->steps[i+1].pj;
+ const auto right_pj_left = pj_left(right_pj);
+ const auto right_pj_right = pj_right(right_pj);
+ if (right_pj_left != right_pj_right || right_pj_left != PJ_IO_UNITS_WHATEVER )
+ {
+ pj->left = right_pj_left;
+ pj->right = right_pj_left;
+ }
+ else if (right_pj_right != PJ_IO_UNITS_WHATEVER)
+ {
+ pj->left = right_pj_right;
+ pj->right = right_pj_right;
+ }
}
}
- for (i=nsteps; i>0;) {
- --i;
+ for (i=1; i<nsteps; i++) {
auto pj = pipeline->steps[i].pj;
if (pj_left(pj) == PJ_IO_UNITS_WHATEVER && pj_right(pj) == PJ_IO_UNITS_WHATEVER) {
- pj->right = get_next_non_whatever_unit(pipeline, i, PJ_INV);
- pj->left = get_next_non_whatever_unit(pipeline, i, PJ_INV);
+ const auto left_pj = pipeline->steps[i-1].pj;
+ const auto left_pj_left = pj_left(left_pj);
+ const auto left_pj_right = pj_right(left_pj);
+ if (left_pj_left != left_pj_right || left_pj_right != PJ_IO_UNITS_WHATEVER )
+ {
+ pj->left = left_pj_right;
+ pj->right = left_pj_right;
+ }
+ else if (left_pj_left != PJ_IO_UNITS_WHATEVER)
+ {
+ pj->left = left_pj_left;
+ pj->right = left_pj_left;
+ }
}
}