Currently I get some console errors in Firefox and Chrome like "SyntaxError: illegal character", "Uncaught SyntaxError: Unexpected token ILLEGAL" or "SyntaxError: expected expression, got ')'". It seems there are some UTF-8 characters that don't belong there. I am still debugging the problem, but my guess it's because of some windows line endings in js-files (but it also happens for inline js).
@mikeytown2: In the issue #2566311-17: JSMin Compression destroy russian characters, you wrote that you have fun with UTF-8 and linked to the StackOverflow issue How to skip invalid characters in XML file using PHP. I was wondering if you have similar problems and/or if the problem is already known?
Comments
Comment #2
osopolarComment #3
osopolarComment #4
mikeytown2 commentedI have not experienced what you're describing with console errors, thus it is unknown to me. The stack overflow code is used in our outbound XML service; we were getting some XML parsing errors on the receiving end due to copy paste characters getting in text fields. That stack overflow code is great for testing things as it can generate every single UTF-8 character and it can also filter out any UTF-8 character you want to.
I already filter out BOM
Comment #5
mikeytown2 commentedHow can I repo this bug?
Comment #6
osopolarComment #7
mikeytown2 commentedComment #8
osopolarActually I am not sure how to reproduce the error, as I can't find what is the cause of it (and the site is quiet large).
What I know so far is, that it seems to happen only with jsmin and the modifier options "Put a wrapper around inline JS if it was added in the content section incorrectly" and/or "Move all inline scripts to the bottom of the execution order" enabled.
Adding
$contents = str_replace("\r", "", $contents);below the code which strips the Byte Order Marks in advagg_js_compress.advagg.inc seems to solve the problem, but I don't know why. Looking at the jsmin code it seems that \r gets replaced by \n, I can't imagine that this would cause any problems, but how knows?Removing the code which strips the BOM
$contents = str_replace(pack("CCC", 0xef, 0xbb, 0xbf), "", $contents);also solves the problem for me (it seems, that I have no js files with BOM).Does this make any sense? I'll set up an minimal drupal installation to see if it happens there too and to find a recipe how to reproduce the problem.
Comment #9
osopolarI disabled advagg_mod and cleared the caches but the illegal character error didn't disappear. So it's not related to processing of inline scripts.
Removing \r as in #8 worked on my Ubuntu (15.10) development environment, but not on the stage server (Gentoo Base System). Removing the BOM removal code
$contents = str_replace(pack("CCC", 0xef, 0xbb, 0xbf), "", $contents);will make the illegal characters disappear – but it doesn't make much sense to me, as the only js files with BOM in my project are the ckeditor scripts, which shouldn't be part of most pages/aggregates.Comment #10
mikeytown2 commentedLook at this issue for inspiration? #2576381: CSS aggregation is broken by files encoded in UTF8 with BOM
Comment #11
steven jones commentedI've got this issue on my site at the moment, using advagg version 7.x-2.16.
I seem to get the 'ILLEGAL character' at the end of files that are being concatenated together when using the jsmin C extension.
On this specific file, I've got a semi-colon and another character:
Hex:
But in the aggregate that the file is built into I have:
Hex:
(I've included up to the added source licensing comment)
Comment #12
steven jones commentedOh, so upgraded to 2.17 and now have some of these in my log:
:(
I'll check installed versions of jsmin, I'm trying to use the C extension version.
Comment #13
steven jones commentedYeah, jsmin 2.0.1.
They had gone away, but just flushed all caches, and the weird characters are back!
Comment #14
mikeytown2 commentedComment #17
nickdickinsonwildeRan into this myself on a production site (D8) that I was updating AdvAgg on which already had JS minification active. I couldn't determine any reason it changed nor why it didn't show up on some of my test sites. However did confirm that is is not directly in AdvAgg - both JSqueeze and JSMin (2.0.1 at least) can do it including when called from a minimal PHP test script.
So added an extra check & fix to 8.x-2.x and back ported that to 7.x-2.x.
Comment #18
nickdickinsonwildeactually doesn't catch all cases...
Comment #19
nickdickinsonwildeThere that gets all cases I've managed to generate.
Comment #20
nickdickinsonwildeComment #22
nickdickinsonwildeNew 7x patch.
Comment #23
mikeytown2 commentedAwesome! Thanks for the patch!
Comment #25
steven jones commentedSeems to be working for me. Thanks!
Comment #26
steven jones commentedGuessing we should try and get this fixed upstream in jsmin?
Comment #27
osopolarThanks NickWilde for working on this.
In my case its not working. I updated the module, cleared all caches multiple times and also cleared advagg files (under AdvAgg: Operations > Drastic Measures). The error message "SyntaxError:illegal character" went away but I get for example the message "SyntaxError: missing ) in parenthetical" (Firefox)or "SyntaxError: Unexpected token ;" (Chrome) due to some other garbage between the javascript code from two different js source files like "(A;" in the following code sniped:
(jQuery);;(A;(function ($) {The code from the patch also assumes that everything after the last occurrence of ";" could be thrown away. But there could be a "}" after the last ";" (see for example advagg.admin.js) which should not be removed.
I also opened an issue for jsmin: https://github.com/sqmk/pecl-jsmin/issues/46.
@NickWilde: May you provide the "minimal PHP test script" which you mentioned in #17? This may help to find the cause of the problem.
Comment #28
mikeytown2 commentedFix for js ending with
}.Comment #29
mikeytown2 commentedComment #30
osopolarThanks mikeytown2, this seems to work, the code makes sense. Anyway I'll observe the problem, as it disappeared once before (when I created patch from #8) and later it came back again.
Comment #31
osopolarIt's still not working for me. Chrome gave me the error "Uncaught ReferenceError: A is not defined" due to this code snipped:
(jQuery);;-A;(function ($) {.Comment #32
mikeytown2 commentedI wonder if we cutoff anything after the
;or}for every file, as in get rid of the if statement from the patch in #28.Comment #33
mikeytown2 commentedBrowsing around other js file and I do see some of them also end in
). Here's the idea from #32Comment #34
osopolarThe problem is, that substr() isn't removing enough, as strrpos gives the position (start counting from 0) and substr third parameter requires a length (which should be position + 1). Simple example: If the string in $contents is just
;thenstrrpos($contents, ';');will return 0, but it's length is 1.Check also:
I hope the patch now fixes the problem.
Comment #35
mikeytown2 commentedGuessing #34 fixes it?
Comment #36
osopolarSo far it's working well for me.
Comment #37
mikeytown2 commentedComment #38
mikeytown2 commented#34 has been committed
Comment #40
osopolarIt worked well the last days on the test environment, but it occurred again today. Maybe the assumption "The first chars varies a bit but the last char is always an ASCII control character" is true for most cases but not for all. I added a patch that removes the if statement. See also #32.
Comment #41
mikeytown2 commented@osopolar
Let me know after a week or two if the patch in #40 is still working. It's a little risky but it should solve the issue, thus why I'm waiting before committing it.
Comment #42
mikeytown2 commented@osopolar
Is #40 still good?
Comment #43
ndobromirov commentedHi all and thanks for the patch :),
I have updated from 2.17 (stable) to latest dev version due to this issue (unsuccessfully), the patch in #40 fixes it.
Moving to Major, as JS is broken on pages with advagg enabled.
Marking #40 as RTBC as it is a working fix.
I think this needs a stable in near future, as the 2.17 broken when using recommended settings (JSMin).
BR, Nikolay Dobromirov.
Comment #45
mikeytown2 commented@ndobromirov
Thanks for the feedback! Jsmin issue is here: https://github.com/sqmk/pecl-jsmin/issues/46
I've committed #40 with the addition of linking to the github issue as well.
Comment #46
andsigno82 commentedhi,
when using curl "patchurl" | git apply -v
i'm getting this error
Checking patch advagg_js_compress/advagg_js_compress.advagg.inc...
error: while searching for:
return;
}
// Under some unknown/rare circumstances, JSMin and JSqueeze can add a
// couple of extraneous/wrong chars at the end of the string. Check and
// remove if necessary.
if (substr(trim($contents), -2) == "\xE3\x7F") {
$contents = substr($contents, 0, -2);
}
// Ensure that $contents ends with ; or }.
error: patch failed: advagg_js_compress/advagg_js_compress.advagg.inc:364
error: advagg_js_compress/advagg_js_compress.advagg.inc: patch does not apply
what I'm doing wrong?
Comment #47
mikeytown2 commented@andsigno82
Patch was rolled from dev, you're trying to patch 7.x-2.17. This has been committed (#44) so using the latest dev will have this patch already applied to it. Reason this conflicts is I committed a fix that worked in most cases in #24 and then #39. So to get this patch to apply to 2.17 you'll need to apply #22, #34 and then #40.
Comment #48
maxtorete commentedI installed the latest dev version but the problem persists. I'm getting this error:
Uncaught ReferenceError: V is not definedAnd this is like the offending code looks like:
If I disable the JS compression it works fine.
Comment #49
maxtorete commentedI deleted manually the folder sites/default/files/advagg_js and now it is working. I thought it should be deleted when clearing caches.
Comment #50
osopolarSorry for late response. I switched the production environment to JSqueeze, as it didn't seem to be save using JSMin. I didn't expire any problems with JSqueeze (unlike to the experience in #17).
The testing environment I set to JSMin and today I got the warning
SyntaxError: expected expression, got ')'again, due to the js code from devel module (devel_krumo_path.js):(jQuery);;);.Comment #51
nickdickinsonwilde@maxtorete ([#49]) - no that is not normally cleared, although AdvAgg does provide an easy way to clear it - under the settings - admin/config/development/performance/advagg/operations under 'drastic operations'
Comment #52
mikeytown2 commented@maxtorete
Clearing the caches does not delete files; you have to go to
admin/config/development/performance/advagg/operationsand under Drastic Measures click the button under "Clear All Files". This is something that is usually not needed.@osopolar
File in question - http://cgit.drupalcode.org/devel/tree/devel_krumo_path.js?h=7.x-1.x. Super strange that
;);was added to it; seems like a parser bug in jsmin.Comment #53
osopolarNormally the JSMin fix seemed to worked fine, and maybe the error in #50 is something different. It occurred when the krumo js from devel was loaded. Would be nice if anybody who tested the fixes of this issue could check if krumo works well for them – just go to /devel/php, run the following code
dpm(array(1,2));and check the browsers console log.@NickWilde: You said in #17 "However did confirm that is is not directly in AdvAgg - both JSqueeze and JSMin (2.0.1 at least) can do it including when called from a minimal PHP test script.". Would you be so kind and provide the minimal PHP test script, that might made it much easier to find the real error (in JSMin), as the above fixes are all just workarounds. Are you sure it happens in JSqueeze too? For me JSqueeze is working well. Maybe it just appeared for JSqueeze due to some caching?
@mikeytown2: Where you able to reproduce the problems with JSMin? For me it only happens on the stage (and live) server (Gentoo Linux) but not on the development environment (Ubuntu 15.10). Maybe there is something wrong with the server configuration.
Comment #54
osopolarAfter the bulletproof cache clearing (
drush advagg-clear-all-files && drush advagg-force-new-aggregates && drush cache-clear all) the error from #50 went away, now I getTypeError: (intermediate value)(...) is not a function, complaining the code:krumo.out=function(el){krumo.unclass(el,'krumo-hover');}(function($){Drupal.toggleFieldset=function(fieldset).The problem goes away if I manually add a ";" after
{krumo.unclass(el,'krumo-hover');}either in the aggregated file or in the original krumo.js. The code in advagg_get_js_aggregate_contents() should prevent the js files "from running together", but therefore the code$contents .= ";/**/\n";should be called afterdrupal_alter('advagg_get_js_file_contents'), shouldn't it?Looking at the source of krumo.js, there are many carriage returns signs (^M), so maybe the bug in JSMin is related to that?
Comment #55
mikeytown2 commentedI've never had this issue so I'm shooting in the dark.
Comment #56
osopolar@mikeytown2: I remember that I read somewhere that the encoding passed to the pecl extension (in this case jsmin) depends on the locale settings of the machine where the code runs. On my test machine LANG is set to "en_US.ISO8859-1". You may try to set
LANG="en_US.ISO8859-1"in /etc/default/locale and then check withlocalein a new terminal window (or better restart the (web-) server). On my development environment it seems that it worked to trigger the problem, after disabling the fix$contents = substr($contents, 0, 1 + max($a, $b, $c));.Comment #57
mikeytown2 commented@osopolar
Sounds like that is something I could check for on the status report page... good to know. We're using CentOS and you're using Ubuntu; this could explain a lot.
Comment #58
mikeytown2 commented@osopolar
what happens when you run
localeon your sever? I get everything coming back as en_US.UTF-8.Comment #59
osopolarI get the following for the (managed) server where the problem occurred:
Not sure if/why LANG matters, as everything else is set to utf8 and afaik LANG provides only the default for the others (see
man 7 locale). But when I changed to LANG=en_US.ISO8859-1 for my local development environment (see #56) I was able to reproduce the problem there too.Comment #60
mikeytown2 commentedHere's some code that should detect if the locale is not UTF-8
Comment #61
osopolar@mikeytown2: Where you able to reproduce the error by setting
LANG=en_US.ISO8859-1(see #56)?Or could anybody else confirm that the problem is related to the locale settings?
Comment #62
mikeytown2 commentedHaven't tested it yet; been focused on #2451801: Empty JS on multilingual's default language pages; sometimes binary (gzip) or 504 as well. 307 issue.
Comment #63
ndobromirov commentedHi again,
The fix from 40 was working until today.
After a new code was deployed to a staging environment the issue is back with different broken symbols.
The script from #60 outputs the following on that server:
Comment #64
mikeytown2 commentedndobromirov
What's your linux distro and its version?
Comment #65
ndobromirov commentedcat /proc/version
cat /etc/*-release
Using PHP 5.5 with the REMI packages, nothing is compiled from source, so nothing is that custom.
Comment #66
mikeytown2 commented@ndobromirov
What do you get when you run
locale -a?Comment #67
ndobromirov commentedHi it appears that it's utf8 and not UTF-8. See in the attached file (ndobromirov-locale--a-info.txt).
Comment #68
mikeytown2 commentedGood to know! My server is also CentOS 6.6, so it seems the UTF8 naming scheme is caused by something else.
Comment #69
mikeytown2 commentedHave a proof of concept code for checking the required min php version and the current jsmin version on github.
I gave a go at this with xpath queries but I didn't have any luck; I think this will work for now.
Comment #70
osopolar<dependencies><required><php><min>5.4.0does not mean that this is he minimum required php version for jsmin, it's just for Travis CI (see https://github.com/c9s/pecl-jsmin/commit/1971ecd075ab8d4749c2fbc2574fad7...). The readme says:Comment #71
ndobromirov commentedSo now it's only this:
LC_ALL = is not UTF 8.I am with PHP 5.5 so I do not think it's PHP's version-related.
Is it possible the internal file encoding to cause the issue?
see this from the JSmin Home-page (http://crockford.com/javascript/jsmin):
So if some of the source files internal encoding in the aggregates is different than UTF-8 it will be undefined/invalid input for JSMin.
I will try to see whether this is the problem is my case sometime today or tomorrow and keep you posted.
Comment #72
mikeytown2 commentedRecently discovered http://php.net/setlocale. Does this fix the issue for people who are having jsmin issues?
Comment #73
mikeytown2 commentedHere's the status report page patch.
Comment #75
mikeytown2 commentedCommitted part of #73; the locale parts are now in this patch.
Comment #76
mikeytown2 commentedI need someone with this issue to test #72 and advagg-2627468-74-status-report-locale.patch in #75. Looking like once I get #2376849: ReferenceError: krumo is not defined & fix js errors inside of krumo.js done I'll be tagging the next release of AdvAgg; I would like to include a better fix for the jsmin issue if at all possible.
Comment #77
ndobromirov commentedHi, This is very strange...
Last time, I was able to reproduce this on all environments (local, integration, stage, life).
I can not reproduce this anywhere now, two weeks later, JSMin works... JMin is still 2.0.1. (4 month old stable release).
No changes were done on the server configurations, just some new code was deployed / developed.
It is custom module logic in pure PHP (cron process), in no way related to JS resources handling.
Keep you posted if this comes up in future and if the patch in#72 & #75 have any effect on fixing it.
At the moment everything works without the patch. Code is in the same state as it was in #40.
Comment #78
osopolarI will test the patch this week.
As the bug does not always happen and not on every aggregation I think it would be a nice feature to have a syntax check for js files on the status page (and, if debug mode is enabled maybe also on every page request).
Comment #79
noahott commentedI was experiencing these "Uncaught SyntaxError: Unexpected token ILLEGAL" (Chrome) and SyntaxError: Invalid character '\u0008' (Safari) errors after moving a site from an Apache server to NGINX on Ubuntu 14.04. I was able to fix the problem by downgrading the PECL JSMin PHP extension from version 2.0.1 to 1.1.0. The PECL release notes mention adding UTF-8 support in version 2.0.0:
https://pecl.php.net/package-changelog.php?package=jsmin&release=2.0.0
Comment #80
mikeytown2 commented@noahott
If you go back to using 2.0.1 and apply #72 does that fix the issue for you? If not what does the status report say when you apply the 2nd patch of #75 (advagg-2627468-74-status-report-locale.patch)?
Comment #81
osopolarI updated advagg to the latest dev (7.x-2.17+65-dev) and applied both patches from #74.
The first surprising thing was the result from the status page:
I get this for both, the testing server and my local development environment (which is different to the result I get when I call locale directly from the cli). Anyway, it's nothing that I can control on the managed server (as the hosting company won't change it).
I added
setlocale(LC_ALL, "en_US.UTF-8");to the settings.php file, enabled jsmin and cleared caches multiple times and incremented global counter to force new aggregates. For some time it looked good, but than I got the same problem again as in #50.BTW: The patch removes the
tags from the status page as they where printed in the status message.
Comment #82
mikeytown2 commentedI was really hoping that setlocale would have fixed it. Changing the servers locale seems like a non starter so at this point I'm thinking of commenting out the latest github version check and pushing out a new advagg version.
Comment #84
mikeytown2 commentedThis code has been removed from the advagg_js_compress.install file as the 2.0.1 version seems to cause issues so recommending that people upgrade to it would be a bad idea at the moment.
Comment #85
sgdev commentedSimilar to @noahott in #79, running Nginx with Ubuntu 14.04 and PHP 5.5. Had to downgrade from PECL JSMin 2.0.1 to 1.1.0, otherwise JS Compression is broken trying to use JSMin.
Comment #86
osopolar@ron_s, @noahott: which module version of advagg where you using and may you post the line (or last characteristic part of the line where the error occurred)?
Comment #87
sgdev commented@osopolar, I'm using 7.x-2.18. It's odd... JS compression was causing errors all over the site, so I downgraded to JSMin 1.1.0 and that fixed things. Now upgraded back to 2.0.1, and the site's JavaScript problems are no longer present.
Still getting errors at the command line when running
drush updatedbordrush ccand a full cache clear is being done:Downgrading to JSMin 1.1.0 fixes the command line error. I'll have to monitor and will post an update if I start seeing the JS errors return. (or maybe the JS errors won't return because the site is actually using JSqueeze at this point as a fall back?)
Comment #88
sgdev commentedSome additional information... I just put a few
dpm's inadvagg_js_compress_prepto see what is happening. If I have JSqueeze as the chosen compressor in /admin/config/development/performance/advagg/js-compress, I get that$compressor = 5andfunction_exists('jsmin') = TRUE(as I would expect).However, if I set JSMin as the chosen compressor, it looks like
advagg_js_compress_prepis never run? I never get any result that the function is called. I haven't tracked up to see what might be causing that result, but just thought I would mention.Edit: the function is being called, just looks like it required several cache clears to get it to run.
Comment #89
mikeytown2 commentedYeah was going to say that I cache css/js compression pretty heavily as they are expensive.
Comment #90
nickdickinsonwildeDone a rather large degree of testing, manipulation and smashing my head into brick walls.
My results are so far not incredibly nice:
- yes the JsMin PHP extension has the problem without Drupal/AdvAgg
- it is close to random - at least I can't find any specific factor that ties them together
- The most freakish: sometimes just re-running on the same file directly after itself will fix it after 2 iterations or 4 or x.
- It can actually add pretty much any number of characters less than 5 - and they can be any character pretty much.
Despite those nasty results I have figured out changes to the post processing - a bit yucky but it works in all cases I've so far found/tested. I'll pop up a patch for 7x too shortly.
Comment #92
nickdickinsonwildeActually, I missed commit 8a896b8 in the 7x branch, @osopolar, did that sufficiently fix it for you?
Comment #93
sgdev commented@NickWilde, is there a 7x branch commit for this issue? I'm looking for 8a896b8 and not seeing it... can you post a link? Thanks!
Comment #94
mikeytown2 commented#44, #40
Comment #95
mikeytown2 commentedWell going to postpone this for now, not much else we can do...
Comment #96
ndobromirov commentedHi as far as I can see the fix is to downgrade to JsMin 1.1.0. I am testing on a new project now with the old version - no problems so far.
Comment #97
osopolar@ndobromirov: The downside of downgrading to jsmin 1.1.0 is #2566311: JSMin Compression destroy russian characters.
Comment #98
manyk commentedIt seems JsMin 2.0.1 generates this problem.
Downgrading to JsMin 2.0.0 solves the problem: no more "illegal character" errors.
Comment #99
loparr commentedI tried to downgrade to JsMi 2.0.0 but the "Uncaught SyntaxError: Unexpected token )" is stil there (and breaks views ui).
Chrome shows that the error is in my case in views-admin.js.
Looking at the compressed code, it seems that jsmin is making up some characters:
Original code:
Compressed code:
jQuery(function(){jQuery(window).bind('resize',Drupal.viewsUi.resizeModal);jQuery(window).bind('scroll',Drupal.viewsUi.resizeModal);});;);;Notice the end of the compressed code.
Any workaround?
Comment #100
franckmarquis commentedI had a similar problem on some files with JSMin 2.0.1, and it had two different origins :
Even if this code is valid, JSMin does like the fact that there is no "{" and "}" after "if" and "else".
Maybe it can help...
Comment #102
mikeytown2 commentedRelated #2896671: UTF-16LE encoded js files are not being added to aggregates correctly; mixed encoding issue.
Comment #103
mikeytown2 commentedI'm thinking this issue is the result of non UTF-8 js files not being converted correctly. I'll need to search thought the code base and have a wrapper for where file_get_contents is; making sure the encoding is correct.
Comment #104
mikeytown2 commentedComment #106
mikeytown2 commented