[Bug] Webdialog callback has trouble handling special characters, even when escaped

Hi,

I’m using a comment callback to add a comment from a web dialog to an item in my Plugin. Since special characters might be possible, I use the javascript function encodeUriComponent(str) to encode those characters.

For example, when I use skp:comment@107%3Dit's (which is skp:comment@107=it's) Sketchup crashes immediately, even if the callback is empty:

Error: #<SyntaxError: <main>: syntax error, unexpected tIDENTIFIER, expecting ')'
('107=it's')
         ^
<main>: unterminated string meets end of file
<main>: syntax error, unexpected end-of-input, expecting ')'
('107=it's')

It does work in the normal irb console:

ruby -v
ruby 2.0.0p247 (2013-06-27) [i386-mingw32]
irb(main):001:0> require 'uri'
=> true
irb(main):002:0> URI.unescape("skp:comment@107%3Dit's")
=> "skp:comment@107=it's"

When I escape the value according to RFC3986, which escapes ' too: skp:comment@107%3Dit%27s, I get the same error.

there’s a thread which includes a test script I posted at SCF a couple of years ago…

CLICK HERE

john

Doesn’t work at all with '

Error: #<SyntaxError: <main>: syntax error, unexpected tIDENTIFIER, expecting ')'
('lid1,it's a bugger')
           ^
<main>: unterminated string meets end of file
<main>: syntax error, unexpected end-of-input, expecting ')'
('lid1,it's a bugger')
                      ^>
SketchUp:1:in `eval'
Error: #<NoMethodError: undefined method `split' for nil:NilClass>
C:/Users/spe.ST-DEVELOPMENT/AppData/Roaming/SketchUp/SketchUp 2016/SketchUp/Plugins/show_encoding_issue.rb:113:in `block in show_problem'
SketchUp:1:in `call'
Error: #<SyntaxError: <main>: syntax error, unexpected tIDENTIFIER, expecting ')'
('lid1,it's a bugger')
           ^
<main>: unterminated string meets end of file
<main>: syntax error, unexpected end-of-input, expecting ')'
('lid1,it's a bugger')
                      ^>
SketchUp:1:in `eval'
Error: #<NoMethodError: undefined method `split' for nil:NilClass>
C:/Users/spe.ST-DEVELOPMENT/AppData/Roaming/SketchUp/SketchUp 2016/SketchUp/Plugins/show_encoding_issue.rb:96:in `block in show_problem'
SketchUp:1:in `call'

I’m on Windows 10, 64bit

The ’ nested within a string delimited by ’ is taken as the end of the enclosing string. You need to escape the ’ in it’s.

I already tried that. Sketchup is using the unescaped value internally, my callback method is empty.

Because the callback always encloses its string within single-quotes you must escape any ' within the passed string.
e.g. in your it's the single-quote needs escaping, so you might think that "it\'s" would work, BUT when passing it to the callback you also need to escape the \ escape character itself !
So pass it as "it\\\'s"

Simply process the passed string through a replace function, so every ' becomes \\\'

string = "it's";
formattedString = string.replace(/'/g, "\\\'");

formattedString >>> "it\\\'s"

Which survives the callback process…
Arriving as it's

It seems my old test file fails depending on a straight or curly apostrophes…

in your snippet the apostrophe is not escaped using encodeUriComponent(str)…

that may be the same underlaying issue…

john

Yes. I’m aware of that. Which is why I tried using an extended version of encodeUriComponent that escapes it's as it%27s. it%27s fails too.

Yes, rfc2396 (which URI.unescape is based on) doesn’t escape !, ', (, ), and *. Those characters can be escaped with a custom method like

function fixedEncodeURIComponent (str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}

But it appears to me that Sketchup itself can’t handle such a string, as it somewhere internally probably uses URI.unescape and encloses the result with ' at a later point which then crashes.

Yes, I can write my own escaping, that is not accidentally unescaped by Sketchup, but this doesn’t seem right to me.

Did you actually try skipping your own encoding trickery and simply using the ‘replace’ code example which I provided.
I find that it works for me just fine…
You saying that your method doesn’t work, is NOT the same as saying that mine is flaky !

Another alternative would be to replace the ’ characters in the string with ` in js, before the callback sends the string.
Then on the Ruby-side you can choose to either accept that back-quote or tr it into a ’ ?
If you never expect the back-quote then swapping to a ’ is OK ??

Not at work right now, but will do it tomorrow. I’m sure it’ll work, but why is that not a bug nonetheless? I’m not doing encoding trickery, Sketchup is and it fails while doing it. **I’m sending it%27s to a callback and Sketchup decides to unescape it in an unsafe/incorrect manner and fails. **