Javascript error with sprintf
-
I am seeing the following javascript error related to
sprintfon a Post admin edit page:Is Pods using
window.sprintf? I see asprintf.min.jsasset underpods/ui. Plugins should not be using anything attached towindowthat is not browser native.-
This topic was modified 1 year, 5 months ago by
therealgilles.
-
This topic was modified 1 year, 5 months ago by
therealgilles.
-
This topic was modified 1 year, 5 months ago by
-
The error message says
syntax error [sprintf] unexpected placeholder.This error means that
sprintfwas passed more placeholders prefixed with%than it expected compared to the number of values provided to fill those placeholders.This means the computer was asked to do something that is physically and mathematically impossible: e.g., fill 3 empty buckets with 2 explicit things.
This error usually happens when a human passes
%to sprintf, not realizing that%%must be used for a literal percentage mark, because%is reserved for denoting a placeholder insprintftemplates.“Should” is a subjective opinion, not a computer error — the error is regarding sprintf template requirements; doesn’t have anything to do with the window object.
Computers are like Mr. Miyagi’s frog: they either do correctly, do not at all, or do the incorrect thing correctly.
Hi @pdclark,
Thank you for your response. In theory you are right now but there is so much more that could go wrong. As you know, the JS
windowobject is shared between all JS scripts, therefore there is no guarantee whatwindow.sprintfis. Another script could be doing something like this:window.sprintf = ('my-sprintf', str, ...args) => someLibrarySprintf(str, ...args);or even this:
window.sprintf = 1;In a shared environment, one cannot predict if another plugin is going to alter a shared function. Best practice advises not to rely on shared objects and use scope that you can define and control. JS bundlers do this really well.
If
pods/uidoes not (re-)definewindow.sprintf, then the placeholder error would not point to thepodsplugin and it would likely instead point to the version of faulty plugin. Right now,podsis obscuring the real issue, which is not helpful and could be avoided. At least, that’s my observation.We would be more than happy to help resolve what template-variable mismatch was passed to
sprintf, causing the reported error. The best place for that technical discussion will likely be a GitHub issue submitted via https://pods.io/submitThe error from
sprintfusually indicates a mismatch between the number of placeholders versus the number of variables passed to the function, so details about the templates, context, and Pods configuration in use will be beneficial in tracking down the cause, especially if the page or fields contain the%character.As for preferences of function scopes and naming conventions, you can certainly submit an additional ticket to that effect. It may be beneficial to consider that in the context of a polyfill,
sprintfis a function first defined in C, a 53-year-old programming language.When a feature of one language or environment is ported to another, it is typically referred to as a polyfill. For example, PHP.js, which ports many PHP convenience functions to JavaScript, scoped to a
phpobject.You are correct that JavaScript scope is an important consideration. However, it is not for security reasons, but to avoid confusion.
JavaScript by definition is a language which can redefine itself:
Just as any authorized script in an application can call
window.sprintf = 1;, one can also callwindow.php.sprintf = 2;orArray.prototype = Hacked();— the last of which would redefine the definition of a core data structure to any arbitrary behavior for all scripts of all scopes.This is how JavaScript is architected. Naming conventions do not prevent this, rather, browser sandboxes and cross-domain security restrictions do.
It is true that scoping variables with discretion can avoid developer confusion. If
sprintf()is defined in the global scope, it was likely done with the understanding thatsprintfis a function which has been understood to follow a certain format in the global scope across many programming language for more than 50 years.A similar functionality added in recent core JavaScript versions would be the tilde string marker, which provides a shorthand for similar string template functionality with a more lenient standard for data validation than sprintf.
As expected, the problematic template string was from another plugin. I already filled a separate issue for it.
A library such as PHP.js or https://github.com/alexei/sprintf.js is not a polyfill. From https://developer.mozilla.org/en-US/docs/Glossary/Polyfill:
A polyfill is a piece of code (usually JavaScript on the Web) used to provide modern functionality on older browsers that do not natively support it.About sprintf in C (and other languages), it’s been modified as recently as 202x due to problems with typing (see https://en.wikipedia.org/wiki/Printf), so yes it’s been mostly stable but there are still possibilities of mismatches. Even the JS sprintf library above was last modified 2 years ago.
My larger point is that in an ecosystem such as WordPress, each (plugin) developer should do their best to avoid creating conflicts with other plugins. This will make both the users’ and the developer’s life easier in the long term. I understand things were wild in 2006 (when jQuery was first introduced) but 19 years later, using private scope should be the norm.
There are already plenty of issues arising from different plugins using different versions of composer packages in PHP. We don’t need more of that in JS.
You’re mentioning a tilde string marker but I don’t see anything like this in the JS core. Are you referring to the bitwise operator used with strings (like
~str.indexOf(...)?).Anyway I won’t file a separate issue about scoping, I hope I got my point across. Whether you want to act on it or not is up to you. I’ll keep the github link in mind for the future.
-
This reply was modified 1 year, 4 months ago by
therealgilles.
-
This reply was modified 1 year, 4 months ago by
therealgilles.
-
This reply was modified 1 year, 4 months ago by
The topic ‘Javascript error with sprintf’ is closed to new replies.