<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[243168] trunk/Source/WebKit</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/243168">243168</a></dd>
<dt>Author</dt> <dd>conrad_shultz@apple.com</dd>
<dt>Date</dt> <dd>2019-03-19 13:35:14 -0700 (Tue, 19 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/242369">r242369</a>): Only use picker-supported UTIs when creating image picker
https://bugs.webkit.org/show_bug.cgi?id=195955

Reviewed by Chris Dumez and Wenson Hsieh.

<a href="http://trac.webkit.org/projects/webkit/changeset/242369">r242369</a> started passing UTIs to -[UIImagePickerController setMediaTypes:] that correspond to types accepted by the
file input element. However, UIImagePickerController expects a specific subset of UTIs. In the worst case, if no
expected types are passed, this can cause a crash.

* UIProcess/ios/forms/WKFileUploadPanel.mm:
(UTIsForMIMETypes):
Return a set rather than an array.
(-[WKFileUploadPanel _mediaTypesForPickerSourceType:]):
Rather than hardcode specific UTIs, ask UIImagePickerController for its available types. If an accepted type
is in the list of available types, use it. Otherwise, if an accepted type conforms to an available type,
use the available type. This is an O(n^2) process, but there typically are only a handful of types, so
this seems acceptable.
(-[WKFileUploadPanel _showDocumentPickerMenu]):
Convert the set from UTIsForMIMETypes() to an array.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosformsWKFileUploadPanelmm">trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (243167 => 243168)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2019-03-19 20:27:51 UTC (rev 243167)
+++ trunk/Source/WebKit/ChangeLog       2019-03-19 20:35:14 UTC (rev 243168)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2019-03-19  Conrad Shultz  <conrad_shultz@apple.com>
+
+        REGRESSION (r242369): Only use picker-supported UTIs when creating image picker
+        https://bugs.webkit.org/show_bug.cgi?id=195955
+
+        Reviewed by Chris Dumez and Wenson Hsieh.
+
+        r242369 started passing UTIs to -[UIImagePickerController setMediaTypes:] that correspond to types accepted by the
+        file input element. However, UIImagePickerController expects a specific subset of UTIs. In the worst case, if no
+        expected types are passed, this can cause a crash.
+
+        * UIProcess/ios/forms/WKFileUploadPanel.mm:
+        (UTIsForMIMETypes):
+        Return a set rather than an array.
+        (-[WKFileUploadPanel _mediaTypesForPickerSourceType:]):
+        Rather than hardcode specific UTIs, ask UIImagePickerController for its available types. If an accepted type
+        is in the list of available types, use it. Otherwise, if an accepted type conforms to an available type,
+        use the available type. This is an O(n^2) process, but there typically are only a handful of types, so
+        this seems acceptable.
+        (-[WKFileUploadPanel _showDocumentPickerMenu]):
+        Convert the set from UTIsForMIMETypes() to an array.
+
</ins><span class="cx"> 2019-03-19  Michael Catanzaro  <mcatanzaro@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         Build cleanly with GCC 9
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosformsWKFileUploadPanelmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm (243167 => 243168)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm     2019-03-19 20:27:51 UTC (rev 243167)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFileUploadPanel.mm        2019-03-19 20:35:14 UTC (rev 243168)
</span><span class="lines">@@ -314,7 +314,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma mark - Media Types
</span><span class="cx"> 
</span><del>-static NSArray *UTIsForMIMETypes(NSArray *mimeTypes)
</del><ins>+static NSSet<NSString *> *UTIsForMIMETypes(NSArray *mimeTypes)
</ins><span class="cx"> {
</span><span class="cx">     NSMutableSet *mediaTypes = [NSMutableSet set];
</span><span class="cx">     for (NSString *mimeType in mimeTypes) {
</span><span class="lines">@@ -322,17 +322,32 @@
</span><span class="cx">         if (!uti.isEmpty())
</span><span class="cx">             [mediaTypes addObject:(__bridge NSString *)uti];
</span><span class="cx">     }
</span><del>-    return mediaTypes.allObjects;
</del><ins>+    return mediaTypes;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (NSArray *)_mediaTypesForPickerSourceType:(UIImagePickerControllerSourceType)sourceType
</del><ins>+- (NSArray<NSString *> *)_mediaTypesForPickerSourceType:(UIImagePickerControllerSourceType)sourceType
</ins><span class="cx"> {
</span><del>-    NSArray *mediaTypes = UTIsForMIMETypes(_mimeTypes.get());
-    if (mediaTypes.count)
</del><ins>+    NSArray<NSString *> *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:sourceType];
+    NSSet<NSString *> *acceptedMediaTypes = UTIsForMIMETypes(_mimeTypes.get());
+    if (acceptedMediaTypes.count) {
+        NSMutableArray<NSString *> *mediaTypes = [NSMutableArray array];
+        for (NSString *availableMediaType in availableMediaTypes) {
+            if ([acceptedMediaTypes containsObject:availableMediaType])
+                [mediaTypes addObject:availableMediaType];
+            else {
+                for (NSString *acceptedMediaType in acceptedMediaTypes) {
+                    if (UTTypeConformsTo((__bridge CFStringRef)acceptedMediaType, (__bridge CFStringRef)availableMediaType)) {
+                        [mediaTypes addObject:availableMediaType];
+                        break;
+                    }
+                }
+            }
+        }
</ins><span class="cx">         return mediaTypes;
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     // Fallback to every supported media type if there is no filter.
</span><del>-    return [UIImagePickerController availableMediaTypesForSourceType:sourceType];
</del><ins>+    return availableMediaTypes;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #pragma mark - Source selection menu
</span><span class="lines">@@ -356,7 +371,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_showDocumentPickerMenu
</span><span class="cx"> {
</span><del>-    NSArray *mediaTypes = UTIsForMIMETypes(_mimeTypes.get());
</del><ins>+    NSArray *mediaTypes = UTIsForMIMETypes(_mimeTypes.get()).allObjects;
</ins><span class="cx"> 
</span><span class="cx">     BOOL containsImageMediaType = !mediaTypes.count || arrayContainsUTIThatConformsTo(mediaTypes, kUTTypeImage);
</span><span class="cx">     BOOL containsVideoMediaType = !mediaTypes.count || arrayContainsUTIThatConformsTo(mediaTypes, kUTTypeMovie);
</span></span></pre>
</div>
</div>

</body>
</html>