Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cesium3DTileStyle string variables substitution sometimes fails #12455

Open
kiselev-dv opened this issue Jan 29, 2025 · 4 comments · May be fixed by #12466
Open

Cesium3DTileStyle string variables substitution sometimes fails #12455

kiselev-dv opened this issue Jan 29, 2025 · 4 comments · May be fixed by #12466
Labels
category - architecture / api good first issue An opportunity for first time contributors type - bug

Comments

@kiselev-dv
Copy link
Contributor

kiselev-dv commented Jan 29, 2025

What happened?

Substitution of variables in Cesium Scene Expression _evaluateVariableString not always substitute all the templates

Node.prototype._evaluateVariableString = function (feature) {
let result = this._value;
let match = variableRegex.exec(result);
while (match !== null) {
const placeholder = match[0];
const variableName = match[1];
let property = getFeatureProperty(feature, variableName);
if (!defined(property)) {
property = "";
}
result = result.replace(placeholder, property);
match = variableRegex.exec(result);
}
return result;
};

Current version uses regex stored in a global variable. In JavaScript regular expression objects are statefull and _evaluateVariableString changes the regexp input string not accounting for regexp object state.

variableRegex keeps lastIndex that lead to an error in following scenario:

  1. Have two variable placeholders in a string
  2. Match first one (at this step lastIndex would point 1 position after variable template)
  3. Rewrite the string with variable value,
  4. For rewritten string, if value is shorter than variable name + 3 lastIndex will point further in rewritten string
  5. If for rewritten string, lastIndex now points after $ sign for second variable template, match will fail and value won't be substituted.

One way to fix it would be to account for result string change in length after the replacement.

variableRegex.lastIndex += (property.length - placeholder.length);

Here is a patch (for whatever reason it fails to upload as a separate file)

diff --git a/packages/engine/Source/Scene/Expression.js b/packages/engine/Source/Scene/Expression.js
index a87be1b094..13b40725cc 100644
--- a/packages/engine/Source/Scene/Expression.js
+++ b/packages/engine/Source/Scene/Expression.js
@@ -1225,6 +1225,7 @@ Node.prototype._evaluateVariableString = function (feature) {
       property = "";
     }
     result = result.replace(placeholder, property);
+    variableRegex.lastIndex += (property.length - placeholder.length);
     match = variableRegex.exec(result);
   }
   return result;

There is a stack overflow question describing how state in JavaScript regexp works https://stackoverflow.com/questions/11477415/why-does-javascripts-regex-exec-not-always-return-the-same-value

Reproduction steps

...

Sandcastle example

No response

Environment

Browser: Firefox
CesiumJS Version: 1.124 1.125
Operating System: Linux Mint

@ggetz
Copy link
Contributor

ggetz commented Feb 6, 2025

Good catch @kiselev-dv! Would you be able to open a PR with the fix?

@ggetz ggetz added category - architecture / api good first issue An opportunity for first time contributors and removed needs triage labels Feb 6, 2025
@kiselev-dv
Copy link
Contributor Author

kiselev-dv commented Feb 6, 2025

Yep, and I'd really appreciate if you tell me how to run a specific test spec. I've tried npx gulp test --specs Specs/Scene/ExpressionSpec.js but it still runs all of the test, which takes quite a while.

UPD: found it nwm

@kiselev-dv kiselev-dv linked a pull request Feb 6, 2025 that will close this issue
6 tasks
@kiselev-dv
Copy link
Contributor Author

Here is a PR #12466

I have signed Contributor License Agreement but it was somewhat like 4 years ago or mb more, I'm not sure if I have to update it.

I'm in CONTRIBUTORS.md but company have changed the name and domain name, and I'm not sure should I update it or not.

@ggetz
Copy link
Contributor

ggetz commented Feb 6, 2025

Awesome, thank you!

I have signed Contributor License Agreement but it was somewhat like 4 years ago or mb more, I'm not sure if I have to update it.

You should still be covered!

I'm in CONTRIBUTORS.md but company have changed the name and domain name, and I'm not sure should I update it or not.

If it is the same organization, please feel free to update their information in CONTRIBUTORS.md. Otherwise, you can add yourself under a new organization as well.

Yep, and I'd really appreciate if you tell me how to run a specific test spec. I've tried npx gulp test --specs Specs/Scene/ExpressionSpec.js but it still runs all of the test, which takes quite a while.

If anyone else needs to know, it's with fit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category - architecture / api good first issue An opportunity for first time contributors type - bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants