<!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>[207397] trunk/Source/WebCore</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/207397">207397</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2016-10-16 18:28:51 -0700 (Sun, 16 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/206750">r206750</a>): Crash when pressing Caps Lock if “Use the Caps Lock key to switch to and from U.S.” is selected in Input Sources preferences
https://bugs.webkit.org/show_bug.cgi?id=163506
&lt;rdar://problem/28792483&gt;

Reviewed by Darin Adler.

As per the NSEvent documentation [1], calling [NSEvent characters] is only
valid on key up / key down events and will raise an NSInternalInconsistencyException
if accessed on any other kind of event object. The crash happens when keyForKeyEvent()
is called with the third kind of key event (NSFlagsChanged) which is used for
detecting modifier keys. We normally detect the modifier key and return early before
calling [NSEvent characters]. However, in some rare cases, we fail to detect the
modifier key and we fall through.

To address the issue, we now return &quot;Unidentified&quot; for NSFlagsChanged events, if we
fail to detect the modifier key and before calling [NSEvent characters].

[1] https://developer.apple.com/reference/appkit/nsevent/1534183-characters

No new test, not easily testable.

* platform/mac/PlatformEventFactoryMac.mm:
(WebCore::keyForKeyEvent):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformmacPlatformEventFactoryMacmm">trunk/Source/WebCore/platform/mac/PlatformEventFactoryMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (207396 => 207397)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-17 00:16:05 UTC (rev 207396)
+++ trunk/Source/WebCore/ChangeLog        2016-10-17 01:28:51 UTC (rev 207397)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2016-10-16  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        REGRESSION (r206750): Crash when pressing Caps Lock if “Use the Caps Lock key to switch to and from U.S.” is selected in Input Sources preferences
+        https://bugs.webkit.org/show_bug.cgi?id=163506
+        &lt;rdar://problem/28792483&gt;
+
+        Reviewed by Darin Adler.
+
+        As per the NSEvent documentation [1], calling [NSEvent characters] is only
+        valid on key up / key down events and will raise an NSInternalInconsistencyException
+        if accessed on any other kind of event object. The crash happens when keyForKeyEvent()
+        is called with the third kind of key event (NSFlagsChanged) which is used for
+        detecting modifier keys. We normally detect the modifier key and return early before
+        calling [NSEvent characters]. However, in some rare cases, we fail to detect the
+        modifier key and we fall through.
+
+        To address the issue, we now return &quot;Unidentified&quot; for NSFlagsChanged events, if we
+        fail to detect the modifier key and before calling [NSEvent characters].
+
+        [1] https://developer.apple.com/reference/appkit/nsevent/1534183-characters
+
+        No new test, not easily testable.
+
+        * platform/mac/PlatformEventFactoryMac.mm:
+        (WebCore::keyForKeyEvent):
+
</ins><span class="cx"> 2016-10-16  Darin Adler  &lt;darin@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Move CSS classes from ExceptionCode to Exception
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacPlatformEventFactoryMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/PlatformEventFactoryMac.mm (207396 => 207397)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/PlatformEventFactoryMac.mm        2016-10-17 00:16:05 UTC (rev 207396)
+++ trunk/Source/WebCore/platform/mac/PlatformEventFactoryMac.mm        2016-10-17 01:28:51 UTC (rev 207397)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> #import &lt;HIToolbox/Events.h&gt;
</span><span class="cx"> #import &lt;mach/mach_time.h&gt;
</span><span class="cx"> #import &lt;wtf/ASCIICType.h&gt;
</span><ins>+#import &lt;wtf/mac/AppKitCompatibilityDeclarations.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -221,11 +222,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline String textFromEvent(NSEvent* event)
</span><span class="cx"> {
</span><del>-#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
</del><span class="cx">     if ([event type] == NSEventTypeFlagsChanged)
</span><del>-#else
-    if ([event type] == NSFlagsChanged)
-#endif
</del><span class="cx">         return emptyString();
</span><span class="cx">     return String([event characters]);
</span><span class="cx"> }
</span><span class="lines">@@ -232,11 +229,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline String unmodifiedTextFromEvent(NSEvent* event)
</span><span class="cx"> {
</span><del>-#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
</del><span class="cx">     if ([event type] == NSEventTypeFlagsChanged)
</span><del>-#else
-    if ([event type] == NSFlagsChanged)
-#endif
</del><span class="cx">         return emptyString();
</span><span class="cx">     return String([event charactersIgnoringModifiers]);
</span><span class="cx"> }
</span><span class="lines">@@ -264,16 +257,18 @@
</span><span class="cx">         return ASCIILiteral(&quot;Control&quot;);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // If the event is an NSEventTypeFlagsChanged events and we have not returned yet then this means we could not
+    // identify the modifier key. We return now and report the key as &quot;Unidentified&quot;.
+    // Note that [event characters] below raises an exception if called on an NSEventTypeFlagsChanged event.
+    if ([event type] == NSEventTypeFlagsChanged)
+        return ASCIILiteral(&quot;Unidentified&quot;);
+
</ins><span class="cx">     // If more than one key is being pressed and the key combination includes one or more modifier keys
</span><span class="cx">     // that result in the key no longer producing a printable character (e.g., Control + a), then the
</span><span class="cx">     // key value should be the printable key value that would have been produced if the key had been
</span><span class="cx">     // typed with the default keyboard layout with no modifier keys except for Shift and AltGr applied.
</span><span class="cx">     // https://w3c.github.io/uievents/#keys-guidelines
</span><del>-#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
</del><span class="cx">     bool isControlDown = ([event modifierFlags] &amp; NSEventModifierFlagControl);
</span><del>-#else
-    bool isControlDown = ([event modifierFlags] &amp; NSControlKeyMask);
-#endif
</del><span class="cx">     NSString *s = isControlDown ? [event charactersIgnoringModifiers] : [event characters];
</span><span class="cx">     auto length = [s length];
</span><span class="cx">     // characters / charactersIgnoringModifiers return an empty string for dead keys.
</span><span class="lines">@@ -500,11 +495,7 @@
</span><span class="cx"> 
</span><span class="cx"> String keyIdentifierForKeyEvent(NSEvent* event)
</span><span class="cx"> {
</span><del>-#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
</del><span class="cx">     if ([event type] == NSEventTypeFlagsChanged) {
</span><del>-#else
-    if ([event type] == NSFlagsChanged) {
-#endif
</del><span class="cx">         switch ([event keyCode]) {
</span><span class="cx">             case 54: // Right Command
</span><span class="cx">             case 55: // Left Command
</span><span class="lines">@@ -692,7 +683,6 @@
</span><span class="cx"> {
</span><span class="cx">     OptionSet&lt;PlatformEvent::Modifier&gt; modifiers;
</span><span class="cx"> 
</span><del>-#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101200
</del><span class="cx">     if (event.modifierFlags &amp; NSEventModifierFlagShift)
</span><span class="cx">         modifiers |= PlatformEvent::Modifier::ShiftKey;
</span><span class="cx">     if (event.modifierFlags &amp; NSEventModifierFlagControl)
</span><span class="lines">@@ -703,18 +693,6 @@
</span><span class="cx">         modifiers |= PlatformEvent::Modifier::MetaKey;
</span><span class="cx">     if (event.modifierFlags &amp; NSEventModifierFlagCapsLock)
</span><span class="cx">         modifiers |= PlatformEvent::Modifier::CapsLockKey;
</span><del>-#else
-    if (event.modifierFlags &amp; NSShiftKeyMask)
-        modifiers |= PlatformEvent::Modifier::ShiftKey;
-    if (event.modifierFlags &amp; NSControlKeyMask)
-        modifiers |= PlatformEvent::Modifier::CtrlKey;
-    if (event.modifierFlags &amp; NSAlternateKeyMask)
-        modifiers |= PlatformEvent::Modifier::AltKey;
-    if (event.modifierFlags &amp; NSCommandKeyMask)
-        modifiers |= PlatformEvent::Modifier::MetaKey;
-    if (event.modifierFlags &amp; NSAlphaShiftKeyMask)
-        modifiers |= PlatformEvent::Modifier::CapsLockKey;
-#endif
</del><span class="cx"> 
</span><span class="cx">     return modifiers;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>