Title: [249095] trunk/Source/_javascript_Core
Revision
249095
Author
[email protected]
Date
2019-08-26 07:36:47 -0700 (Mon, 26 Aug 2019)

Log Message

Missing media controls when WebKit is built with Python3
https://bugs.webkit.org/show_bug.cgi?id=194367

Reviewed by Carlos Garcia Campos.

The _javascript_ minifier script jsmin.py expects a text stream
with text type as input, but the script make-js-file-arrays.py
was passing to it a FileIO() object. So, when the jsmin script
called read() over this object, python3 was returning a type of
bytes, but for python2 it returns type str.

This caused two problems: first that jsmin failed to do any minifying
because it was comparing strings with a variable of type bytes.
The second major problem was in the write() function, when the
jsmin script tried to convert a byte character to text by calling
str() on it. Because what this does is not to convert from byte
type to string, but to simply generate a string with the format b'c'.
So the jsmin script was returning back as minified JS complete
garbage in the form of "b't'b'h'b'h'b'i" for python3.

Therefore, when WebKit was built with python3 this broke everything
that depended on the embedded JS code that make-js-file-arrays.py
was supposed to generate, like the media controls and the WebDriver
atoms.

Fix this by reworking the code in make-js-file-arrays script to
read the data from the file using a TextIOWrapper in python 3
with decoding for 'utf-8'. This ensures that the jsmin receives
a text type. For python2 keep using the same FileIO class.

On the jsmin.py script remove the problematic call to str() inside
the write() function when running with python3.
On top of that, add an extra check in jsmin.py script to make it
fail if the character type read is not the one expected. This
will cause the build to fail instead of failing silently like
now. I did some tests and the runtime cost of this extra check
is almost zero.

* Scripts/jsmin.py:
(_javascript_Minify.minify.write):
(_javascript_Minify):
* Scripts/make-js-file-arrays.py:
(main):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (249094 => 249095)


--- trunk/Source/_javascript_Core/ChangeLog	2019-08-26 09:41:28 UTC (rev 249094)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-08-26 14:36:47 UTC (rev 249095)
@@ -1,3 +1,49 @@
+2019-08-26  Carlos Alberto Lopez Perez  <[email protected]>
+
+        Missing media controls when WebKit is built with Python3
+        https://bugs.webkit.org/show_bug.cgi?id=194367
+
+        Reviewed by Carlos Garcia Campos.
+
+        The _javascript_ minifier script jsmin.py expects a text stream
+        with text type as input, but the script make-js-file-arrays.py
+        was passing to it a FileIO() object. So, when the jsmin script
+        called read() over this object, python3 was returning a type of
+        bytes, but for python2 it returns type str.
+
+        This caused two problems: first that jsmin failed to do any minifying
+        because it was comparing strings with a variable of type bytes.
+        The second major problem was in the write() function, when the
+        jsmin script tried to convert a byte character to text by calling
+        str() on it. Because what this does is not to convert from byte
+        type to string, but to simply generate a string with the format b'c'.
+        So the jsmin script was returning back as minified JS complete
+        garbage in the form of "b't'b'h'b'h'b'i" for python3.
+
+        Therefore, when WebKit was built with python3 this broke everything
+        that depended on the embedded JS code that make-js-file-arrays.py
+        was supposed to generate, like the media controls and the WebDriver
+        atoms.
+
+        Fix this by reworking the code in make-js-file-arrays script to
+        read the data from the file using a TextIOWrapper in python 3
+        with decoding for 'utf-8'. This ensures that the jsmin receives
+        a text type. For python2 keep using the same FileIO class.
+
+        On the jsmin.py script remove the problematic call to str() inside
+        the write() function when running with python3.
+        On top of that, add an extra check in jsmin.py script to make it
+        fail if the character type read is not the one expected. This
+        will cause the build to fail instead of failing silently like
+        now. I did some tests and the runtime cost of this extra check
+        is almost zero.
+
+        * Scripts/jsmin.py:
+        (_javascript_Minify.minify.write):
+        (_javascript_Minify):
+        * Scripts/make-js-file-arrays.py:
+        (main):
+
 2019-08-23  Devin Rousso  <[email protected]>
 
         Web Inspector: create additional command line api functions for other console methods

Modified: trunk/Source/_javascript_Core/Scripts/jsmin.py (249094 => 249095)


--- trunk/Source/_javascript_Core/Scripts/jsmin.py	2019-08-26 09:41:28 UTC (rev 249094)
+++ trunk/Source/_javascript_Core/Scripts/jsmin.py	2019-08-26 14:36:47 UTC (rev 249095)
@@ -28,6 +28,7 @@
 is_3 = sys.version_info >= (3, 0)
 if is_3:
     import io
+    python_text_type = str
 else:
     import StringIO
     try:
@@ -34,6 +35,7 @@
         import cStringIO
     except ImportError:
         cStringIO = None
+    python_text_type = basestring
 
 
 __all__ = ['jsmin', '_javascript_Minify']
@@ -82,14 +84,15 @@
             if str(char) in 'return':
                 self.return_buf += char
                 self.is_return = self.return_buf == 'return'
-            if sys.version_info.major == 2:
-                self.outs.write(char)
-            else:
-                self.outs.write(str(char))
+            self.outs.write(char)
             if self.is_return:
                 self.return_buf = ''
 
-        read = self.ins.read
+        def read(n):
+            char = self.ins.read(n)
+            if not isinstance(char, python_text_type):
+                raise ValueError("ERROR: The script jsmin.py can only handle text input, but it received input of type %s" % type(char))
+            return char
 
         space_strings = "abcdefghijklmnopqrstuvwxyz"\
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$\\"

Modified: trunk/Source/_javascript_Core/Scripts/make-js-file-arrays.py (249094 => 249095)


--- trunk/Source/_javascript_Core/Scripts/make-js-file-arrays.py	2019-08-26 09:41:28 UTC (rev 249094)
+++ trunk/Source/_javascript_Core/Scripts/make-js-file-arrays.py	2019-08-26 14:36:47 UTC (rev 249095)
@@ -26,11 +26,8 @@
 import os
 from optparse import OptionParser
 import sys
-if sys.version_info.major == 2:
-    from StringIO import StringIO
-else:
-    from io import StringIO
-from jsmin import _javascript_Minify
+from jsmin import jsmin
+is_3 = sys.version_info >= (3, 0)
 
 
 def stringifyCodepoint(code):
@@ -71,25 +68,34 @@
     print('#include "{0:s}"'.format(os.path.basename(headerPath)), file=sourceFile)
     print('namespace {0:s} {{'.format(namespace), file=sourceFile)
 
-    jsm = _javascript_Minify()
-
     for inputFileName in inputPaths:
-        inputStream = io.FileIO(inputFileName)
-        outputStream = StringIO()
 
+        if is_3:
+            inputStream = io.open(inputFileName, encoding='utf-8')
+        else:
+            inputStream = io.FileIO(inputFileName)
+
+        data = ""
+
         if not options.no_minify:
-            jsm.minify(inputStream, outputStream)
-            characters = outputStream.getvalue()
+            characters = jsmin(data)
         else:
-            characters = inputStream.read()
+            characters = data
 
-        size = len(characters)
+        if is_3:
+            codepoints = bytearray(characters, encoding='utf-8')
+        else:
+            codepoints = list(map(ord, characters))
+
+        # Use the size of codepoints instead of the characters
+        # because UTF-8 characters may need more than one byte.
+        size = len(codepoints)
+
         variableName = os.path.splitext(os.path.basename(inputFileName))[0]
 
         print('extern const char {0:s}_javascript_[{1:d}];'.format(variableName, size), file=headerFile)
         print('const char {0:s}_javascript_[{1:d}] = {{'.format(variableName, size), file=sourceFile)
 
-        codepoints = list(map(ord, characters))
         for codepointChunk in chunk(codepoints, 16):
             print('    {0:s},'.format(','.join(map(stringifyCodepoint, codepointChunk))), file=sourceFile)
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to